amqp-utils 0.0.1 → 0.2.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.
- data/.gitignore +5 -0
- data/Rakefile +68 -4
- data/TODO.txt +7 -0
- data/VERSION +1 -0
- data/amqp-utils.gemspec +79 -0
- data/bin/amqp-deleteq +7 -3
- data/bin/amqp-dequeue +20 -8
- data/bin/amqp-enqueue +14 -6
- data/bin/amqp-peek +12 -7
- data/bin/amqp-pop +12 -6
- data/bin/amqp-purge +47 -0
- data/bin/amqp-statq +8 -4
- data/lib/amqp_utils/command.rb +66 -20
- data/lib/amqp_utils/message_formatter.rb +42 -0
- data/lib/amqp_utils.rb +9 -1
- metadata +44 -37
- data/Manifest.txt +0 -25
- data/config/hoe.rb +0 -75
- data/config/requirements.rb +0 -15
- data/lib/amqp_utils/version.rb +0 -9
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -9
data/Rakefile
CHANGED
@@ -1,4 +1,68 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "amqp-utils"
|
8
|
+
gem.summary = %Q{Command line utilities for interacting with AMQP compliant queues}
|
9
|
+
gem.description = %Q{Command line utilies for interacting with AMQP compliant queues.
|
10
|
+
The intention is provide simple management tools that can be used to complete ad hoc
|
11
|
+
housework on an AMQP queue. In addition, simple scripts can be layered over the tools
|
12
|
+
when needed.}
|
13
|
+
gem.email = "dougbarth@gmail.com"
|
14
|
+
gem.homepage = "http://github.com/dougbarth/amqp-utils"
|
15
|
+
gem.authors = ["Doug Barth"]
|
16
|
+
gem.rubyforge_project = "amqp-utils"
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
|
19
|
+
gem.add_dependency('tmm1-amqp', '~> 0.6.4')
|
20
|
+
gem.add_dependency('trollop', '~> 1.10.2')
|
21
|
+
gem.add_dependency('facets', '~> 2.7.0')
|
22
|
+
gem.add_dependency('clio', '~> 0.3.0')
|
23
|
+
gem.add_dependency('json', '~> 1.1.6')
|
24
|
+
end
|
25
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
26
|
+
rubyforge.doc_task = "rdoc"
|
27
|
+
end
|
28
|
+
rescue LoadError
|
29
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'rake/testtask'
|
33
|
+
Rake::TestTask.new(:test) do |test|
|
34
|
+
test.libs << 'lib' << 'test'
|
35
|
+
test.pattern = 'test/**/*_test.rb'
|
36
|
+
test.verbose = true
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
require 'rcov/rcovtask'
|
41
|
+
Rcov::RcovTask.new do |test|
|
42
|
+
test.libs << 'test'
|
43
|
+
test.pattern = 'test/**/*_test.rb'
|
44
|
+
test.verbose = true
|
45
|
+
end
|
46
|
+
rescue LoadError
|
47
|
+
task :rcov do
|
48
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :test => :check_dependencies
|
53
|
+
|
54
|
+
task :default => :test
|
55
|
+
|
56
|
+
require 'rake/rdoctask'
|
57
|
+
Rake::RDocTask.new do |rdoc|
|
58
|
+
if File.exist?('VERSION')
|
59
|
+
version = File.read('VERSION')
|
60
|
+
else
|
61
|
+
version = ""
|
62
|
+
end
|
63
|
+
|
64
|
+
rdoc.rdoc_dir = 'rdoc'
|
65
|
+
rdoc.title = "amqp-utils #{version}"
|
66
|
+
rdoc.rdoc_files.include('README*')
|
67
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
68
|
+
end
|
data/TODO.txt
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
[x] fix amqp-enqueue message count
|
2
|
+
[x] detect commandline ARGV when no queue is specified bring up help
|
3
|
+
[x] amqp-stat hangs when no queue specified
|
4
|
+
[x] amqp-enqueue inspect error when message not specified
|
5
|
+
[o] amqp-dequeue hangs on exit
|
6
|
+
[o] setup.rb seems to install command.rb in wrong location
|
7
|
+
[o] gem create
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
data/amqp-utils.gemspec
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{amqp-utils}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Doug Barth"]
|
12
|
+
s.date = %q{2009-11-13}
|
13
|
+
s.description = %q{Command line utilies for interacting with AMQP compliant queues.
|
14
|
+
The intention is provide simple management tools that can be used to complete ad hoc
|
15
|
+
housework on an AMQP queue. In addition, simple scripts can be layered over the tools
|
16
|
+
when needed.}
|
17
|
+
s.email = %q{dougbarth@gmail.com}
|
18
|
+
s.executables = ["amqp-deleteq", "amqp-dequeue", "amqp-enqueue", "amqp-peek", "amqp-pop", "amqp-purge", "amqp-statq"]
|
19
|
+
s.extra_rdoc_files = [
|
20
|
+
"README.txt"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".gitignore",
|
24
|
+
"History.txt",
|
25
|
+
"License.txt",
|
26
|
+
"README.txt",
|
27
|
+
"Rakefile",
|
28
|
+
"TODO.txt",
|
29
|
+
"VERSION",
|
30
|
+
"amqp-utils.gemspec",
|
31
|
+
"bin/amqp-deleteq",
|
32
|
+
"bin/amqp-dequeue",
|
33
|
+
"bin/amqp-enqueue",
|
34
|
+
"bin/amqp-peek",
|
35
|
+
"bin/amqp-pop",
|
36
|
+
"bin/amqp-purge",
|
37
|
+
"bin/amqp-statq",
|
38
|
+
"lib/amqp_utils.rb",
|
39
|
+
"lib/amqp_utils/command.rb",
|
40
|
+
"lib/amqp_utils/message_formatter.rb",
|
41
|
+
"test/test_amqp_utils.rb",
|
42
|
+
"test/test_helper.rb"
|
43
|
+
]
|
44
|
+
s.homepage = %q{http://github.com/dougbarth/amqp-utils}
|
45
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
46
|
+
s.require_paths = ["lib"]
|
47
|
+
s.rubyforge_project = %q{amqp-utils}
|
48
|
+
s.rubygems_version = %q{1.3.5}
|
49
|
+
s.summary = %q{Command line utilities for interacting with AMQP compliant queues}
|
50
|
+
s.test_files = [
|
51
|
+
"test/test_amqp_utils.rb",
|
52
|
+
"test/test_helper.rb"
|
53
|
+
]
|
54
|
+
|
55
|
+
if s.respond_to? :specification_version then
|
56
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
60
|
+
s.add_runtime_dependency(%q<tmm1-amqp>, ["~> 0.6.4"])
|
61
|
+
s.add_runtime_dependency(%q<trollop>, ["~> 1.10.2"])
|
62
|
+
s.add_runtime_dependency(%q<facets>, ["~> 2.7.0"])
|
63
|
+
s.add_runtime_dependency(%q<clio>, ["~> 0.3.0"])
|
64
|
+
s.add_runtime_dependency(%q<json>, ["~> 1.1.6"])
|
65
|
+
else
|
66
|
+
s.add_dependency(%q<tmm1-amqp>, ["~> 0.6.4"])
|
67
|
+
s.add_dependency(%q<trollop>, ["~> 1.10.2"])
|
68
|
+
s.add_dependency(%q<facets>, ["~> 2.7.0"])
|
69
|
+
s.add_dependency(%q<clio>, ["~> 0.3.0"])
|
70
|
+
s.add_dependency(%q<json>, ["~> 1.1.6"])
|
71
|
+
end
|
72
|
+
else
|
73
|
+
s.add_dependency(%q<tmm1-amqp>, ["~> 0.6.4"])
|
74
|
+
s.add_dependency(%q<trollop>, ["~> 1.10.2"])
|
75
|
+
s.add_dependency(%q<facets>, ["~> 2.7.0"])
|
76
|
+
s.add_dependency(%q<clio>, ["~> 0.3.0"])
|
77
|
+
s.add_dependency(%q<json>, ["~> 1.1.6"])
|
78
|
+
end
|
79
|
+
end
|
data/bin/amqp-deleteq
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
4
|
|
@@ -7,12 +7,16 @@ class QueueDeleteCommand < AmqpUtils::Command
|
|
7
7
|
options.banner %Q{
|
8
8
|
|Deletes the supplied queues.
|
9
9
|
|
|
10
|
-
| #{command_name} <queue>[
|
10
|
+
| #{command_name} <queue> [<another queue> ...]
|
11
11
|
}.margin
|
12
12
|
end
|
13
13
|
|
14
|
+
def validate
|
15
|
+
raise "need at least one queue name" unless args[0] && !args[0].empty?
|
16
|
+
end
|
17
|
+
|
14
18
|
def execute
|
15
|
-
@queues =
|
19
|
+
@queues = args
|
16
20
|
def @queues.delete_or_stop
|
17
21
|
queue = pop
|
18
22
|
if queue
|
data/bin/amqp-dequeue
CHANGED
@@ -1,28 +1,40 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
|
+
require File.dirname(__FILE__) + '/../lib/amqp_utils/message_formatter'
|
4
5
|
|
5
6
|
class DequeueCommand < AmqpUtils::Command
|
6
7
|
def prepare_options(options)
|
7
8
|
options.banner %Q{
|
8
9
|
|Removes messages from the supplied queues and displays them on STDOUT.
|
9
10
|
|
|
10
|
-
| #{command_name} <queue>[
|
11
|
+
| #{command_name} <queue> [<another queue> ...]
|
12
|
+
|
|
13
|
+
|Dequeue options:
|
11
14
|
}.margin
|
15
|
+
options.opt :format, 'The format that the messages should be displayed as',
|
16
|
+
:short => :none, :default => 'pretty'
|
17
|
+
options.opt :quiet, 'Suppresses non-message content output',
|
18
|
+
:short => 'q', :default => false
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate
|
22
|
+
raise "need at least one queue name" if args.empty?
|
12
23
|
end
|
13
24
|
|
14
25
|
def execute
|
15
|
-
@queues =
|
26
|
+
@queues = args
|
27
|
+
@formatter = AmqpUtils::MessageFormatter.for_type(options[:format])
|
28
|
+
|
16
29
|
@queues.each do |queue|
|
17
|
-
puts "Dequeueing from #{queue}..."
|
30
|
+
puts "Dequeueing from #{queue} (^C to stop)..." unless options[:quiet]
|
18
31
|
mq = MQ.new
|
19
32
|
|
20
33
|
process_message = lambda do |header, message|
|
21
|
-
puts "(#{queue})"
|
22
|
-
|
23
|
-
puts " Message: #{message.inspect}"
|
34
|
+
puts "(#{queue})" unless options[:quiet]
|
35
|
+
@formatter.generate(STDOUT, header, message)
|
24
36
|
end
|
25
|
-
mq.queue(queue).subscribe
|
37
|
+
mq.queue(queue).subscribe(&process_message)
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
data/bin/amqp-enqueue
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
|
+
require 'clio/progressbar'
|
4
5
|
|
5
6
|
class EnqueueCommand < AmqpUtils::Command
|
6
7
|
def prepare_options(options)
|
@@ -11,28 +12,35 @@ class EnqueueCommand < AmqpUtils::Command
|
|
11
12
|
|
|
12
13
|
|Enqueue options:
|
13
14
|
}.margin
|
14
|
-
options.opt :persistent, 'Mark messages as persistent.'
|
15
|
+
options.opt :persistent, 'Mark messages as persistent.', :short => :none
|
15
16
|
options.opt :count, 'Number of times the message should be published.', :type => :int, :default => 1
|
16
17
|
end
|
17
18
|
|
19
|
+
def validate
|
20
|
+
raise "need a queue to publish to" unless args[0] && !args[0].empty?
|
21
|
+
raise "need a message to publish" unless args[1] && !args[1].empty?
|
22
|
+
end
|
23
|
+
|
18
24
|
def execute
|
19
|
-
@queue =
|
20
|
-
@message = ARGV[1]
|
25
|
+
@queue, @message = args
|
21
26
|
|
22
27
|
publisher = EM.spawn do |queue, message, messages, options|
|
28
|
+
@progress ||= Clio::Progressbar.new('Enqueuing', options[:count])
|
29
|
+
|
23
30
|
if messages > 0
|
24
31
|
@mq ||= MQ.new
|
25
32
|
@mq.queue(queue, :durable => true, :auto_delete => false).
|
26
33
|
publish(message, :persistent => options.persistent)
|
27
34
|
|
28
|
-
|
35
|
+
@progress.inc
|
29
36
|
publisher.notify(queue, message, messages - 1, options)
|
30
37
|
else
|
38
|
+
@progress.finish
|
31
39
|
EM.next_tick { AMQP.stop { EM.stop } }
|
32
40
|
end
|
33
41
|
end
|
34
42
|
|
35
|
-
publisher.notify(@queue, @message, options
|
43
|
+
publisher.notify(@queue, @message, options[:count], options)
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
data/bin/amqp-peek
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
|
+
require File.dirname(__FILE__) + '/../lib/amqp_utils/message_formatter'
|
4
5
|
|
5
6
|
class PeekCommand < AmqpUtils::Command
|
6
7
|
def prepare_options(options)
|
@@ -12,22 +13,26 @@ class PeekCommand < AmqpUtils::Command
|
|
12
13
|
| NOTE: This operation does have side effects on the server. The message is
|
13
14
|
| placed at the end of the queue after returning from this method. The
|
14
15
|
| message is also marked as being redelivered.
|
16
|
+
|
|
17
|
+
|Peek options:
|
15
18
|
}.margin
|
19
|
+
options.opt :format, 'The format that the messages should be displayed as',
|
20
|
+
:short => :none, :default => 'pretty'
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate
|
24
|
+
raise "need a queue name" unless args[0] && !args[0].empty?
|
16
25
|
end
|
17
26
|
|
18
27
|
def execute
|
19
28
|
@queue = args[0]
|
29
|
+
@formatter = AmqpUtils::MessageFormatter.for_type(options[:format])
|
20
30
|
|
21
31
|
mq = MQ.new
|
22
|
-
|
23
32
|
mq.queue(@queue).pop(:ack => true) do |header, message|
|
24
33
|
if message
|
25
34
|
puts "(#{@queue})"
|
26
|
-
|
27
|
-
header.properties.each do |key, value|
|
28
|
-
puts " #{key.inspect} => #{value.inspect}"
|
29
|
-
end
|
30
|
-
puts " Message: #{message.inspect}"
|
35
|
+
@formatter.generate(STDOUT, header, message)
|
31
36
|
else
|
32
37
|
puts "(#{@queue}) empty"
|
33
38
|
end
|
data/bin/amqp-pop
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
|
+
require File.dirname(__FILE__) + '/../lib/amqp_utils/message_formatter'
|
4
5
|
|
5
6
|
class PopCommand < AmqpUtils::Command
|
6
7
|
def prepare_options(options)
|
@@ -8,21 +9,26 @@ class PopCommand < AmqpUtils::Command
|
|
8
9
|
|Pops a single message from the queue.
|
9
10
|
|
|
10
11
|
| #{command_name} <queue>
|
12
|
+
|
|
13
|
+
|Pop options:
|
11
14
|
}.margin
|
15
|
+
options.opt :format, 'The format that the messages should be displayed as',
|
16
|
+
:short => :none, :default => 'pretty'
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate
|
20
|
+
raise "need a queue name" unless args[0] && !args[0].empty?
|
12
21
|
end
|
13
22
|
|
14
23
|
def execute
|
15
24
|
@queue = args[0]
|
25
|
+
@formatter = AmqpUtils::MessageFormatter.for_type(options[:format])
|
16
26
|
|
17
27
|
mq = MQ.new
|
18
28
|
mq.queue(@queue).pop do |header, message|
|
19
29
|
if message
|
20
30
|
puts "(#{@queue})"
|
21
|
-
|
22
|
-
header.properties.each do |key, value|
|
23
|
-
puts " #{key.inspect} => #{value.inspect}"
|
24
|
-
end
|
25
|
-
puts " Message: #{message.inspect}"
|
31
|
+
@formatter.generate(STDOUT, header, message)
|
26
32
|
else
|
27
33
|
puts "(#{@queue}) empty"
|
28
34
|
end
|
data/bin/amqp-purge
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
|
+
|
5
|
+
# Monkey patching in purge support.
|
6
|
+
#
|
7
|
+
# TODO: submit this change back to the AMQP project.
|
8
|
+
class MQ::Queue
|
9
|
+
def purge(options = {})
|
10
|
+
@mq.callback {
|
11
|
+
@mq.send Protocol::Queue::Purge.new({:queue => name,
|
12
|
+
:nowait => true}.merge(options))
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class PurgeCommand < AmqpUtils::Command
|
18
|
+
def prepare_options(options)
|
19
|
+
options.banner %Q{
|
20
|
+
|Removes all messages from the supplied queues.
|
21
|
+
|
|
22
|
+
| #{command_name} <queue> [<another queue> ...]
|
23
|
+
}.margin
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
raise "need at least one queue name" if args.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute
|
31
|
+
mq = MQ.new
|
32
|
+
@queues = args
|
33
|
+
purge_one = lambda do
|
34
|
+
queue = @queues.shift
|
35
|
+
puts "Purging #{queue}..."
|
36
|
+
mq.queue(queue).purge
|
37
|
+
if @queues.empty?
|
38
|
+
AMQP.stop { EM.stop }
|
39
|
+
else
|
40
|
+
EM.next_tick(&purge_one)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
EM.next_tick(&purge_one)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
PurgeCommand.run
|
data/bin/amqp-statq
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
|
4
4
|
|
@@ -7,15 +7,19 @@ class QueueStatCommand < AmqpUtils::Command
|
|
7
7
|
options.banner %Q{
|
8
8
|
|Gets statistics on the queues specified.
|
9
9
|
|
|
10
|
-
| #{command_name} <queue> [<another_queue>
|
10
|
+
| #{command_name} <queue> [<another_queue> ...]
|
11
11
|
}.margin
|
12
12
|
end
|
13
13
|
|
14
|
+
def validate
|
15
|
+
raise "need at least one queue name" unless args[0] && !args[0].empty?
|
16
|
+
end
|
17
|
+
|
14
18
|
def execute
|
15
|
-
@queues =
|
19
|
+
@queues = args
|
16
20
|
|
17
21
|
@queues.each do |queue|
|
18
|
-
|
22
|
+
mq.queue(queue, :passive => true).status do |size, consumers|
|
19
23
|
puts "Queue <#{queue}>: #{size} message(s), #{consumers} consumer(s)"
|
20
24
|
|
21
25
|
@queues.delete(queue)
|
data/lib/amqp_utils/command.rb
CHANGED
@@ -1,10 +1,19 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../amqp_utils'
|
2
2
|
|
3
3
|
class AmqpUtils::Command
|
4
|
+
include Clio::Terminal
|
5
|
+
|
4
6
|
class << self
|
5
7
|
def run(args = ARGV)
|
6
8
|
command = new(args)
|
7
9
|
command.process_options
|
10
|
+
|
11
|
+
begin
|
12
|
+
command.validate
|
13
|
+
rescue RuntimeError => e
|
14
|
+
Trollop::die(e.message)
|
15
|
+
end
|
16
|
+
|
8
17
|
command.go
|
9
18
|
end
|
10
19
|
end
|
@@ -13,25 +22,43 @@ class AmqpUtils::Command
|
|
13
22
|
@args = args
|
14
23
|
end
|
15
24
|
|
25
|
+
def version
|
26
|
+
IO.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION'))
|
27
|
+
end
|
28
|
+
|
16
29
|
attr_reader :args, :options
|
17
30
|
|
18
31
|
def process_options
|
19
32
|
command = self
|
20
33
|
@options = Trollop::options(@args) do
|
34
|
+
version(command.version)
|
21
35
|
command.prepare_options(self) if command.respond_to?(:prepare_options)
|
22
36
|
|
23
37
|
banner %Q{
|
24
38
|
|
|
25
39
|
|Standard options:
|
26
40
|
}.margin
|
27
|
-
opt :host, 'The AMQP host to connect to', :default => 'localhost'
|
28
|
-
opt :port, 'The AMQP port to connect to', :default => 5672
|
29
|
-
opt :vhost, 'The vhost to connect to', :default => '/'
|
30
|
-
opt :user, 'The user name to authenticate with', :default => 'guest'
|
31
|
-
opt :
|
32
|
-
opt :
|
33
|
-
|
41
|
+
opt :host, 'The AMQP host to connect to', :short => 'H', :default => 'localhost'
|
42
|
+
opt :port, 'The AMQP port to connect to', :short => 'P', :default => 5672
|
43
|
+
opt :vhost, 'The vhost to connect to', :short => 'V', :default => '/'
|
44
|
+
opt :user, 'The user name to authenticate with', :default => 'guest', :short => 'u'
|
45
|
+
opt :prompt, 'Prompt the user for a password', :short => 'p'
|
46
|
+
opt :password, 'The password to connect with.', :default => 'guest', :short => :none
|
47
|
+
conflicts(:prompt, :password)
|
48
|
+
opt :timeout, 'The connect timeout in seconds', :default => 5, :short => 't'
|
49
|
+
opt :verbose, 'Print all AMQP commands sent and received.', :short => 'v'
|
34
50
|
end
|
51
|
+
|
52
|
+
@args = @args.dup
|
53
|
+
ARGV.clear
|
54
|
+
end
|
55
|
+
|
56
|
+
# Called to validate that the supplied command line options and arguments
|
57
|
+
# are valid. If there is a problem with the supplied values, and exception
|
58
|
+
# should be raised.
|
59
|
+
#
|
60
|
+
# Subclasses show override this method and do their validation.
|
61
|
+
def validate
|
35
62
|
end
|
36
63
|
|
37
64
|
def command_name
|
@@ -39,23 +66,42 @@ class AmqpUtils::Command
|
|
39
66
|
end
|
40
67
|
|
41
68
|
def go
|
42
|
-
|
43
|
-
|
44
|
-
|
69
|
+
if options.prompt
|
70
|
+
options[:password] = password()
|
71
|
+
puts
|
72
|
+
end
|
73
|
+
|
74
|
+
%w(host port vhost user timeout).each do |val|
|
75
|
+
AMQP.settings[val.to_sym] = options[val.to_sym]
|
76
|
+
end
|
77
|
+
AMQP.settings[:pass] = options.password
|
78
|
+
AMQP.logging = options.verbose
|
79
|
+
|
80
|
+
trap("INT") do
|
81
|
+
if @nice_tried
|
82
|
+
EM.stop
|
83
|
+
else
|
84
|
+
AMQP.stop { EM.stop }
|
85
|
+
@nice_tried = true
|
45
86
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
if
|
51
|
-
|
52
|
-
else
|
53
|
-
AMQP.stop { EM.stop }
|
54
|
-
@nice_tried = true
|
87
|
+
end
|
88
|
+
|
89
|
+
EM.run do
|
90
|
+
amqp.connection_status do |status|
|
91
|
+
if status == :disconnected
|
92
|
+
Trollop::die "disconnected from #{AMQP.settings[:host]}:#{AMQP.settings[:port]}"
|
55
93
|
end
|
56
94
|
end
|
57
95
|
|
58
|
-
execute
|
96
|
+
mq.callback { execute }
|
59
97
|
end
|
60
98
|
end
|
99
|
+
|
100
|
+
def amqp
|
101
|
+
@amqp ||= AMQP.start
|
102
|
+
end
|
103
|
+
|
104
|
+
def mq
|
105
|
+
@mq ||= MQ.new
|
106
|
+
end
|
61
107
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class AmqpUtils::MessageFormatter
|
2
|
+
class << self
|
3
|
+
@@formatters ||= {}
|
4
|
+
|
5
|
+
def for_type(format_type)
|
6
|
+
@@formatters[format_type.downcase].new
|
7
|
+
end
|
8
|
+
|
9
|
+
def register_formatter(formatter, format_type)
|
10
|
+
@@formatters[format_type.downcase] = formatter
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Base
|
15
|
+
def self.inherited(klass)
|
16
|
+
::AmqpUtils::MessageFormatter.register_formatter(klass, klass.basename)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Pretty < Base
|
21
|
+
def generate(io, header, message)
|
22
|
+
io.puts " Header: "
|
23
|
+
header.properties.each do |key, value|
|
24
|
+
io.puts " #{key.inspect} => #{value.inspect}"
|
25
|
+
end
|
26
|
+
io.puts " Message: #{message.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class JSON < Base
|
31
|
+
def generate(io, header, message)
|
32
|
+
json_obj = {'header' => header.properties, 'message' => message}
|
33
|
+
io.puts ::JSON.generate(json_obj)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Message < Base
|
38
|
+
def generate(io, header, message)
|
39
|
+
io.puts message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/amqp_utils.rb
CHANGED
@@ -10,8 +10,16 @@ require 'rubygems'
|
|
10
10
|
gem 'trollop'
|
11
11
|
require 'trollop'
|
12
12
|
|
13
|
-
gem 'amqp'
|
13
|
+
gem 'tmm1-amqp'
|
14
14
|
require 'mq'
|
15
15
|
|
16
16
|
gem 'facets'
|
17
17
|
require 'facets/string/tab'
|
18
|
+
require 'facets/kernel/returning'
|
19
|
+
require 'facets/module/basename'
|
20
|
+
|
21
|
+
gem 'clio'
|
22
|
+
require 'clio/consoleutils'
|
23
|
+
|
24
|
+
gem 'json'
|
25
|
+
require 'json'
|