amqpcat-hw 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+ # gem "bunny", "~> 0.7.0"
3
+ gem 'bunny', :git => 'git://github.com/ruby-amqp/bunny.git'
@@ -0,0 +1,15 @@
1
+ GIT
2
+ remote: git://github.com/ruby-amqp/bunny.git
3
+ revision: f2deea037057169014b0f7a67682baf6a9d70c30
4
+ specs:
5
+ bunny (0.8.0.pre1)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bunny!
@@ -0,0 +1,106 @@
1
+ amqpcat - Netcat-like tool for AMQP queues
2
+ ==========================================
3
+
4
+ This was originally written as a "toy" to learn and experiment with
5
+ rabbitmq. It allows you to easily read/write from AMQP queues/exchanges
6
+ from the command line or from shell scripts. It is implemented with the
7
+ `bunny` Ruby gem.
8
+
9
+ Install
10
+ -------
11
+ Install from gem:
12
+
13
+ sudo gem install amqpcat
14
+
15
+ Install from github:
16
+
17
+ git clone https://github.com/joemiller/amqpcat
18
+ gem build amqpcat.gemspec
19
+ gem install amqpcat-0.0.1.gem
20
+
21
+ Example Usage
22
+ -------------
23
+
24
+ ### 1:1 Messaging
25
+
26
+ Start a consumer. This will block until a message is received.
27
+
28
+ amqpcat --consumer amqp://guest:guest@rabbitmq.server/
29
+
30
+ Publish a message:
31
+
32
+ echo "hello rabbit" | amqpcat --publisher amqp://guest:guest@rabbitmq.server/
33
+
34
+ The consumer should output the message and exit.
35
+
36
+ ### 1:N (fanout / pubsub)
37
+
38
+ See the `examples/test_fanout.sh` script for another example of fanout
39
+ messaging.
40
+
41
+ Start 2 consumers, using `-s` to prefix the output of each with an
42
+ identifying string:
43
+
44
+ amqpcat --consumer -n fanout.test -t fanout -s "Consumer 1: " amqp://guest:guest@rabbitmq.server/
45
+ amqpcat --consumer -n fanout.test -t fanout -s "Consumer 2: " amqp://guest:guest@rabbitmq.server/
46
+
47
+ Note: In fanout mode, consumers will create their own server-named queues and bind to an exchange
48
+ defined by the `-n` parameter.
49
+
50
+ Published a message to the exchange:
51
+
52
+ echo "hello rabbits" | amqpcat --publisher -n fanout.test -t fanout amqp://guest:guest@rabbitmq.server/
53
+
54
+ Both of the consumers should print out the message we published.
55
+
56
+ Options
57
+ -------
58
+ Run `amqpcat -h` to get detailed help output.
59
+
60
+ ### One-message -vs- Continuous message mode
61
+
62
+ By default, when publishing, `amqpcat` will use the newline character to
63
+ distinguish between messages to publish. However, you can send a single
64
+ message by using the `--once` option. This can be useful if you need
65
+ to send a single message that contains new lines.
66
+
67
+ SSL Support
68
+ -----------
69
+ SSL support has been written but is not tested nor is it fully working
70
+ at this time (v0.0.1).
71
+
72
+ Additionally, the --ssl-key and --ssl-cert options are only supported
73
+ under newer versions of the Bunny gem (0.8+) or if bunny is installed
74
+ from the master branch on github.
75
+
76
+ Contributing
77
+ ------------
78
+ 1. Fork it.
79
+ 2. Create a branch (`git checkout -b my_feature`)
80
+ 3. Commit your changes (`git commit -am "did some stuff"`)
81
+ 4. Push to the branch (`git push origin my_feature`)
82
+ 5. Create an with a link to your branch
83
+
84
+ Author
85
+ ------
86
+
87
+ Joe Miller - http://twitter.com/miller_joe || https://github.com/joemiller
88
+
89
+ License
90
+ -------
91
+
92
+ Author:: Joe Miller (<joeym@joeym.net>)
93
+ Copyright:: Copyright (c) 2012 Joe Miller
94
+ License:: Apache License, Version 2.0
95
+
96
+ Licensed under the Apache License, Version 2.0 (the "License");
97
+ you may not use this file except in compliance with the License.
98
+ You may obtain a copy of the License at
99
+
100
+ http://www.apache.org/licenses/LICENSE-2.0
101
+
102
+ Unless required by applicable law or agreed to in writing, software
103
+ distributed under the License is distributed on an "AS IS" BASIS,
104
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
105
+ See the License for the specific language governing permissions and
106
+ limitations under the License.
@@ -0,0 +1,32 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ $:.push('lib')
4
+ require "amqpcat/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "amqpcat-hw"
8
+ s.version = Amqpcat::VERSION.dup
9
+ s.date = "2012-02-05"
10
+ s.summary = "Netcat-like tool for reading and writing messages to AMQP message brokers"
11
+ s.email = "joeym@joeym.net"
12
+ s.homepage = "https://github.com/joemiller/amqpcat"
13
+ s.authors = ['Joe Miller']
14
+
15
+ s.description = <<-EOF
16
+ A netcat inspired command line tool for reading and writing simple
17
+ messages to AMQP based message brokers such as RabbitMQ.
18
+ EOF
19
+
20
+ s.files = Dir['**/*']
21
+ s.test_files = Dir['test/**/*'] + Dir['spec/**/*']
22
+ s.executables = Dir['bin/*'].map { |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ ## Make sure you can build the gem on older versions of RubyGems too:
26
+ s.rubygems_version = "1.3.6"
27
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
28
+ s.specification_version = 3 if s.respond_to? :specification_version
29
+
30
+ s.add_dependency("bunny", "0.7.8")
31
+
32
+ end
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'optparse'
6
+ require 'amqpcat'
7
+
8
+ options = {}
9
+ optparse = OptionParser.new do |opts|
10
+ opts.banner = <<-EOS
11
+ Usage: #{$0} [options] amqp-url
12
+
13
+ amqp-url format: 'amqp://user:pass@host:port/vhost'
14
+
15
+ 'amqp' : required. Either amqp or amqps (SSL)
16
+ 'user:pass' : optional. Default: guest:guest
17
+ 'host' : required.
18
+ 'port' : optional. Default: 5672 (amqp), 5671 (amqps)
19
+ 'vhost' : optional. Default: /
20
+
21
+ Options:
22
+ EOS
23
+
24
+ opts.on('-h', '--help', 'Display usage') { puts opts; exit 0 }
25
+
26
+ options[:mode] = nil
27
+ opts.on('-c', '--consumer', 'Read data from the queue specified by -n and write to STDOUT') do
28
+ options[:mode] = :consumer
29
+ end
30
+
31
+ opts.on('-p', '--publisher', 'Read data from STDIN and publish to the exchange specified by -n') do
32
+ options[:mode] = :publisher
33
+ end
34
+
35
+ opts.on('-k', '--ssl-key FILE', 'Use SSL key in FILE.') do |f|
36
+ options[:ssl_key] = f
37
+ end
38
+
39
+ opts.on('-r', '--ssl-cert FILE', 'Use SSL cert in FILE.') do |f|
40
+ options[:ssl_cert] = f
41
+ end
42
+
43
+ options[:verify_ssl] = true
44
+ opts.on('y', '--[no-]verify-ssl', 'Verify server SSL certficiate. (Default: true)') do |y|
45
+ options[:verify_ssl] = y
46
+ end
47
+
48
+ options[:prefix] = ''
49
+ opts.on('-s', '--string STRING', "prefix output with STRING") do |s|
50
+ options[:prefix] = s
51
+ end
52
+
53
+ options[:once] = false
54
+ opts.on('-o', '--once', "Read/Write one message then exit. (Default: false)") do
55
+ options[:once] = true
56
+ end
57
+
58
+ options[:name] = 'amqpcat.default'
59
+ opts.on('-n', '--name NAME', "Queue and Exchange NAME to use. (Default: amqpcat.default)") do |name|
60
+ options[:name] = name
61
+ end
62
+
63
+ options[:type] = 'direct'
64
+ opts.on('-t', '--type TYPE', "Exchange type: direct, fanout. (Default: direct)") do |type|
65
+ options[:type] = type
66
+ end
67
+
68
+ options[:durable] = true
69
+ opts.on('--[no-]durable', "Enable/Disable durable messages. (Default: durable=true)") do |d|
70
+ options[:durable] = d
71
+ end
72
+
73
+ options[:auto_delete] = false
74
+ opts.on('--[no-]auto_delete', "Enable/Disable auto_delete. (Default: auto_delete=false)") do |d|
75
+ options[:auto_delete] = d
76
+ end
77
+
78
+ opts.on('--routing-key KEY', "Bind or publish to the exchange with a routing key.") do |k|
79
+ options[:routing_key] = k
80
+ end
81
+
82
+ end
83
+ optparse.parse!
84
+
85
+ if ARGV.size < 1
86
+ puts "Must specify amqp-url. --help for help"
87
+ exit 1
88
+ end
89
+
90
+ if options[:mode].nil?
91
+ puts "Must specify --consumer or --publisher. --help for help"
92
+ exit 1
93
+ end
94
+
95
+ amqp_url = ARGV[0]
96
+ amqpcat = Amqpcat.new(amqp_url, options)
97
+
98
+ trap 'SIGINT', proc { amqpcat.finish; exit 0 }
99
+
100
+ case options[:mode]
101
+ when :consumer
102
+ amqpcat.subscribe do |msg|
103
+ $stdout.write options[:prefix] + msg[:payload]
104
+ $stdout.flush
105
+ if options[:once]
106
+ amqpcat.finish
107
+ exit
108
+ end
109
+ end
110
+ when :publisher
111
+ if options[:once]
112
+ amqpcat.publish $stdin.read
113
+ else
114
+ $stdin.each_line { |l| amqpcat.publish(l) }
115
+ end
116
+ end
117
+
118
+ amqpcat.finish
@@ -0,0 +1,20 @@
1
+ #!/bin/sh
2
+
3
+ amqpcat_bin="`dirname $0`/../bin/amqpcat"
4
+
5
+ url="amqp://guest:guest@rabbitmq/"
6
+ opts="--name=direct.test --type=direct"
7
+
8
+ ## start 2 consumers ##
9
+ $amqpcat_bin -s "Consumer 1: " --consumer $url $opts &
10
+ $amqpcat_bin -s "Consumer 2: " --consumer $url $opts &
11
+
12
+ ## send messages ##
13
+ echo "test direct queue: 1" | $amqpcat_bin --publisher $url $opts
14
+ echo "test direct queue: 2" | $amqpcat_bin --publisher $url $opts
15
+ echo "test direct queue: 3" | $amqpcat_bin --publisher $url $opts
16
+ echo "test direct queue: 4" | $amqpcat_bin --publisher $url $opts
17
+
18
+ ## kill the consumers we forked ##
19
+ sleep 1
20
+ kill %1 %2
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+
3
+ amqpcat_bin="`dirname $0`/../bin/amqpcat"
4
+
5
+ amqp_url="amqp://guest:guest@rabbitmq/"
6
+ amqp_opts="--name=fanout.test --type=fanout"
7
+
8
+ ## start 2 consumers ##
9
+ $amqpcat_bin -s "Consumer 1: " $amqp_url $amqp_opts &
10
+ $amqpcat_bin -s "Consumer 2: " $amqp_url $amqp_opts &
11
+ sleep 1
12
+
13
+ ## send messages ##
14
+ echo "test fanout queue: 1" | $amqpcat_bin $amqp_url $amqp_opts
15
+ echo "test fanout queue: 2" | $amqpcat_bin $amqp_url $amqp_opts
16
+ echo "test fanout queue: 3" | $amqpcat_bin $amqp_url $amqp_opts
17
+ echo "test fanout queue: 4" | $amqpcat_bin $amqp_url $amqp_opts
18
+
19
+ ## kill the consumers we forked ##
20
+ sleep 1
21
+ kill %1 %2
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+
3
+ whereami=$(dirname $0)
4
+ amqpcat_bin="$whereami/../bin/amqpcat"
5
+
6
+ url="amqps://guest:guest@rabbitmq/"
7
+ opts="--name=direct.test --type=direct \
8
+ --ssl-key=$whereami/client_key.pem \
9
+ --ssl-cert=$whereami/client_cert.pem\
10
+ --no-verify-ssl"
11
+
12
+ ## start 2 consumers ##
13
+ $amqpcat_bin -s "Consumer 1: " --consumer $url $opts &
14
+ $amqpcat_bin -s "Consumer 2: " --consumer $url $opts &
15
+
16
+ ## send messages ##
17
+ echo "test direct queue: 1" | $amqpcat_bin --publisher $url $opts
18
+ echo "test direct queue: 2" | $amqpcat_bin --publisher $url $opts
19
+ echo "test direct queue: 3" | $amqpcat_bin --publisher $url $opts
20
+ echo "test direct queue: 4" | $amqpcat_bin --publisher $url $opts
21
+
22
+ ## kill the consumers we forked ##
23
+ sleep 1
24
+ kill %1 %2
@@ -0,0 +1,86 @@
1
+ require 'uri'
2
+ require 'bunny'
3
+
4
+ class Amqpcat
5
+ DEFAULT_QUEUE = 'amqpcat.default'
6
+
7
+ def initialize(url, options={})
8
+ parse_amqp_url(url)
9
+
10
+ @opts = {
11
+ :type => 'direct',
12
+ :name => DEFAULT_QUEUE,
13
+ :durable => true,
14
+ :auto_delete => false,
15
+ :persistent => true,
16
+ :ssl_key => nil,
17
+ :ssl_cert => nil,
18
+ :verify_ssl => true,
19
+ }.merge(options)
20
+
21
+ @amqp_settings.merge!(@opts)
22
+ @amqp = Bunny.new(@amqp_settings)
23
+ @amqp.start
24
+ end
25
+
26
+ def publish(msg)
27
+ exchange.publish(msg, :persistent => @opts[:persistent], :key => @opts[:routing_key])
28
+ end
29
+
30
+ def message_count
31
+ queue.message_count
32
+ end
33
+
34
+ def fetch
35
+ queue.pop[:payload]
36
+ end
37
+
38
+ def subscribe(&block)
39
+ queue.subscribe(&block)
40
+ end
41
+
42
+ def finish
43
+ @amqp.stop
44
+ end
45
+
46
+ private
47
+
48
+ def parse_amqp_url(str)
49
+ url = URI.parse(str)
50
+ use_ssl = url.scheme.downcase == 'amqps'
51
+ @amqp_settings = {
52
+ :host => url.host,
53
+ :port => url.port || (use_ssl ? 5671 : 5672),
54
+ :user => url.user || 'guest',
55
+ :pass => url.password || 'guest',
56
+ :vhost => url.path == "" ? '/' : url.path,
57
+ :ssl => use_ssl,
58
+ }
59
+ end
60
+
61
+ def exchange
62
+ return @exchange if @exchange
63
+ options = {
64
+ :type => @opts[:type],
65
+ :durable => @opts[:durable],
66
+ :auto_delete => @opts[:auto_delete]
67
+ }
68
+ @exchange = @amqp.exchange(@opts[:name], options)
69
+ end
70
+
71
+ def queue
72
+ return @queue if @queue
73
+ options = {
74
+ :durable => @opts[:durable],
75
+ :auto_delete => @opts[:auto_delete]
76
+ }
77
+ @queue = case @opts[:type]
78
+ when 'fanout'
79
+ @amqp.queue(options)
80
+ else
81
+ @amqp.queue(@opts[:name], options)
82
+ end
83
+ @queue.bind(exchange, :routing_key => @opts[:routing_key])
84
+ @queue
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ module Amqpcat
2
+ VERSION = '0.0.2'
3
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amqpcat-hw
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Joe Miller
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ type: :runtime
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.8
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - '='
27
+ - !ruby/object:Gem::Version
28
+ version: 0.7.8
29
+ name: bunny
30
+ description: ! 'A netcat inspired command line tool for reading and writing simple
31
+
32
+ messages to AMQP based message brokers such as RabbitMQ.
33
+
34
+ '
35
+ email: joeym@joeym.net
36
+ executables:
37
+ - amqpcat
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - Gemfile
42
+ - Gemfile.lock
43
+ - bin/amqpcat
44
+ - lib/amqpcat/version.rb
45
+ - lib/amqpcat.rb
46
+ - examples/test_ssl.sh
47
+ - examples/test_direct.sh
48
+ - examples/test_fanout.sh
49
+ - amqpcat.gemspec
50
+ - README.md
51
+ homepage: https://github.com/joemiller/amqpcat
52
+ licenses: []
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 1.8.24
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Netcat-like tool for reading and writing messages to AMQP message brokers
75
+ test_files: []