bunny 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Chris Duncan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,49 @@
1
+ = Bunny: A synchronous Ruby AMQP client
2
+
3
+ *GitHub* *repo*: http://github.com/celldee/bunny
4
+
5
+ === DESCRIPTION:
6
+
7
+ Bunny is an AMQP[http://www.amqp.org] (Advanced Message Queuing Protocol) client, written in Ruby, that is intended to allow you to interact with AMQP-compliant message brokers/servers such as RabbitMQ[http://www.rabbitmq.com] in a synchronous fashion.
8
+
9
+ It is based on a great deal of useful code from amqp[http://github.com/tmm1/amqp] by Aman Gupta and Carrot[http://github.com/famoseagle/carrot] by Amos Elliston.
10
+
11
+ You can use Bunny to -
12
+
13
+ * Create and delete exchanges
14
+ * Create and delete queues
15
+ * Publish and consume messages
16
+
17
+ Bunny is known to work with RabbitMQ version 1.5.4 and version 0-8 of the AMQP specification.
18
+
19
+ === INSTALL:
20
+
21
+ *Rubyforge*: <tt>gem install bunny</tt>
22
+
23
+ *GitHub*: <tt>gem install celldee-bunny</tt>
24
+
25
+ === QUICK START:
26
+
27
+ require 'bunny'
28
+
29
+ b = Bunny::Client.new(:logging => true)
30
+
31
+ # start a communication session with the amqp server
32
+ b.start
33
+
34
+ # declare a queue
35
+ q = b.queue('test1')
36
+
37
+ # publish a message to the queue
38
+ q.publish('Hello everybody!')
39
+
40
+ # get message from the queue
41
+ msg = q.pop
42
+
43
+ puts 'This is the message: ' + msg + "\n\n"
44
+
45
+ # close the connection
46
+ b.stop
47
+
48
+ === OTHER:
49
+ Please see the _examples_ directory for additional usage information.
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  task :codegen do
2
- sh 'ruby protocol/codegen.rb > lib/amqp/spec.rb'
3
- sh 'ruby lib/amqp/spec.rb'
2
+ sh 'ruby ext/codegen.rb > lib/bunny/protocol/spec.rb'
3
+ sh 'ruby lib/bunny/protocol/spec.rb'
4
4
  end
5
5
 
6
6
  task :spec do
@@ -8,5 +8,4 @@ task :spec do
8
8
  Spec::Rake::SpecTask.new do |t|
9
9
  t.spec_opts = ['--color']
10
10
  end
11
- end
12
-
11
+ end
@@ -0,0 +1,37 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{bunny}
3
+ s.version = "0.3.0"
4
+ s.authors = ["Chris Duncan"]
5
+ s.date = %q{2009-05-10}
6
+ s.description = %q{Another synchronous Ruby AMQP client}
7
+ s.email = %q{celldee@gmail.com}
8
+ s.rubyforge_project = %q{bunny-amqp}
9
+ s.has_rdoc = true
10
+ s.extra_rdoc_files = [ "README" ]
11
+ s.rdoc_options = [ "--main", "README" ]
12
+ s.homepage = %q{http://github.com/celldee/bunny}
13
+ s.summary = %q{A synchronous Ruby AMQP client that enables interaction with AMQP-compliant brokers/servers.}
14
+ s.files = ["LICENSE",
15
+ "README",
16
+ "Rakefile",
17
+ "bunny.gemspec",
18
+ "examples/simple.rb",
19
+ "examples/simple_ack.rb",
20
+ "examples/simple_consumer.rb",
21
+ "examples/simple_fanout.rb",
22
+ "examples/simple_publisher.rb",
23
+ "examples/simple_topic.rb",
24
+ "ext/amqp-0.8.json",
25
+ "ext/codegen.rb",
26
+ "lib/bunny.rb",
27
+ "lib/bunny/client.rb",
28
+ "lib/bunny/exchange.rb",
29
+ "lib/bunny/protocol/protocol.rb",
30
+ "lib/bunny/protocol/spec.rb",
31
+ "lib/bunny/queue.rb",
32
+ "lib/bunny/transport/buffer.rb",
33
+ "lib/bunny/transport/frame.rb",
34
+ "spec/bunny_spec.rb",
35
+ "spec/exchange_spec.rb",
36
+ "spec/queue_spec.rb"]
37
+ end
@@ -10,7 +10,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
10
10
 
11
11
  require 'bunny'
12
12
 
13
- b = Bunny.new(:logging => true)
13
+ b = Bunny::Client.new(:logging => true)
14
14
 
15
15
  # start a communication session with the amqp server
16
16
  b.start
@@ -10,7 +10,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
10
10
 
11
11
  require 'bunny'
12
12
 
13
- b = Bunny.new(:logging => true)
13
+ b = Bunny::Client.new(:logging => true)
14
14
 
15
15
  # start a communication session with the amqp server
16
16
  b.start
@@ -27,7 +27,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
27
27
 
28
28
  require 'bunny'
29
29
 
30
- b = Bunny.new(:logging => true)
30
+ b = Bunny::Client.new(:logging => true)
31
31
 
32
32
  # start a communication session with the amqp server
33
33
  b.start
@@ -10,7 +10,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
10
10
 
11
11
  require 'bunny'
12
12
 
13
- b = Bunny.new(:logging => true)
13
+ b = Bunny::Client.new(:logging => true)
14
14
 
15
15
  # start a communication session with the amqp server
16
16
  b.start
@@ -12,7 +12,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
12
12
 
13
13
  require 'bunny'
14
14
 
15
- b = Bunny.new(:logging => true)
15
+ b = Bunny::Client.new(:logging => true)
16
16
 
17
17
  # start a communication session with the amqp server
18
18
  b.start
@@ -10,7 +10,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
10
10
 
11
11
  require 'bunny'
12
12
 
13
- b = Bunny.new
13
+ b = Bunny::Client.new
14
14
 
15
15
  # start a communication session with the amqp server
16
16
  b.start
@@ -50,9 +50,9 @@ msg = rugby.pop
50
50
  puts 'This is a message from the rugby q: ' + msg + "\n\n"
51
51
 
52
52
  # allsport queue got all of the messages
53
- until msg == 'QUEUE EMPTY' do
53
+ until msg == :queue_empty do
54
54
  msg = allsport.pop
55
- puts 'This is a message from the allsport q: ' + msg + "\n\n" unless msg == 'QUEUE EMPTY'
55
+ puts 'This is a message from the allsport q: ' + msg + "\n\n" unless msg == :queue_empty
56
56
  end
57
57
 
58
58
  # close the client connection
File without changes
@@ -0,0 +1,177 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+
4
+ name = 'amqp-0.8.json'
5
+ path = File.dirname(__FILE__)+'/'+name
6
+ s = JSON.parse(File.read(path))
7
+
8
+ # require 'pp'
9
+ # pp(s)
10
+ # exit
11
+
12
+ require 'erb'
13
+
14
+ puts ERB.new(%q[
15
+ #:stopdoc:
16
+ # this file was autogenerated on <%= Time.now.to_s %>
17
+ # using <%= name.ljust(16) %> (mtime: <%= File.mtime(path) %>)
18
+ #
19
+ # DO NOT EDIT! (edit ext/codegen.rb instead, and run `rake codegen`)
20
+
21
+ module Bunny
22
+ module Transport
23
+ class Frame
24
+ def self.types
25
+ @types ||= {}
26
+ end
27
+
28
+ def self.Frame id
29
+ (@_base_frames ||= {})[id] ||= Class.new(Frame) do
30
+ class_eval %[
31
+ def self.inherited klass
32
+ klass.const_set(:ID, #{id})
33
+ Frame.types[#{id}] = klass
34
+ end
35
+ ]
36
+ end
37
+ end
38
+
39
+ <%- s['constants'].select{|c| (1..8).include? c['value'] }.each do |c| -%>
40
+ class <%= c['name'].gsub(/^FRAME-/,'').split('-').map{|w| w.downcase.capitalize}.join.ljust(9) -%> < Frame( <%= c['value'] -%> ); end
41
+ <%- end -%>
42
+
43
+ FOOTER = <%= frame_end = s['constants'].find{|c| c['name'] == 'FRAME-END' }['value'] %>
44
+ end
45
+ end
46
+ end
47
+
48
+ module Bunny
49
+ module Protocol
50
+ HEADER = <%= s['name'].dump %>.freeze
51
+ VERSION_MAJOR = <%= s['major-version'] %>
52
+ VERSION_MINOR = <%= s['minor-version'] %>
53
+ PORT = <%= s['port'] %>
54
+
55
+ RESPONSES = {
56
+ <%- s['constants'].select{|c| c['value'] != frame_end and (200..500).include? c['value'] }.each do |c| -%>
57
+ <%= c['value'] %> => :<%= c['name'].tr('-', '_').gsub(/^FRAME_/,'').upcase -%>,
58
+ <%- end -%>
59
+ }
60
+
61
+ FIELDS = [
62
+ <%- s['domains'].select{|d| d.first == d.last }.each do |d| -%>
63
+ :<%= d.first -%>,
64
+ <%- end -%>
65
+ ]
66
+
67
+ class Class
68
+ class << self
69
+ FIELDS.each do |f|
70
+ class_eval %[
71
+ def #{f} name
72
+ properties << [ :#{f}, name ] unless properties.include?([:#{f}, name])
73
+ attr_accessor name
74
+ end
75
+ ]
76
+ end
77
+
78
+ def properties() @properties ||= [] end
79
+
80
+ def id() self::ID end
81
+ def name() self::NAME end
82
+ end
83
+
84
+ class Method
85
+ class << self
86
+ FIELDS.each do |f|
87
+ class_eval %[
88
+ def #{f} name
89
+ arguments << [ :#{f}, name ] unless arguments.include?([:#{f}, name])
90
+ attr_accessor name
91
+ end
92
+ ]
93
+ end
94
+
95
+ def arguments() @arguments ||= [] end
96
+
97
+ def parent() Protocol.const_get(self.to_s[/Protocol::(.+?)::/,1]) end
98
+ def id() self::ID end
99
+ def name() self::NAME end
100
+ end
101
+
102
+ def == b
103
+ self.class.arguments.inject(true) do |eql, (type, name)|
104
+ eql and __send__("#{name}") == b.__send__("#{name}")
105
+ end
106
+ end
107
+ end
108
+
109
+ def self.methods() @methods ||= {} end
110
+
111
+ def self.Method(id, name)
112
+ @_base_methods ||= {}
113
+ @_base_methods[id] ||= ::Class.new(Method) do
114
+ class_eval %[
115
+ def self.inherited klass
116
+ klass.const_set(:ID, #{id})
117
+ klass.const_set(:NAME, :#{name.to_s})
118
+ klass.parent.methods[#{id}] = klass
119
+ klass.parent.methods[klass::NAME] = klass
120
+ end
121
+ ]
122
+ end
123
+ end
124
+ end
125
+
126
+ def self.classes() @classes ||= {} end
127
+
128
+ def self.Class(id, name)
129
+ @_base_classes ||= {}
130
+ @_base_classes[id] ||= ::Class.new(Class) do
131
+ class_eval %[
132
+ def self.inherited klass
133
+ klass.const_set(:ID, #{id})
134
+ klass.const_set(:NAME, :#{name.to_s})
135
+ Protocol.classes[#{id}] = klass
136
+ Protocol.classes[klass::NAME] = klass
137
+ end
138
+ ]
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ module Bunny
145
+ module Protocol
146
+ <%- s['classes'].each do |c| -%>
147
+ class <%= c['name'].capitalize.ljust(12) %> < Class( <%= c['id'].to_s.rjust(3) %>, :<%= c['name'].ljust(12) %> ); end
148
+ <%- end -%>
149
+
150
+ <%- s['classes'].each do |c| -%>
151
+ class <%= c['name'].capitalize %>
152
+ <%- c['properties'].each do |p| -%>
153
+ <%= p['type'].ljust(10) %> :<%= p['name'].tr('-','_') %>
154
+ <%- end if c['properties'] -%>
155
+
156
+ <%- c['methods'].each do |m| -%>
157
+ class <%= m['name'].capitalize.gsub(/-(.)/){ "#{$1.upcase}"}.ljust(12) %> < Method( <%= m['id'].to_s.rjust(3) %>, :<%= m['name'].tr('- ','_').ljust(14) %> ); end
158
+ <%- end -%>
159
+
160
+ <%- c['methods'].each do |m| -%>
161
+ class <%= m['name'].capitalize.gsub(/-(.)/){ "#{$1.upcase}"} %>
162
+ <%- m['arguments'].each do |a| -%>
163
+ <%- if a['domain'] -%>
164
+ <%= s['domains'].find{|k,v| k == a['domain']}.last.ljust(10) %> :<%= a['name'].tr('- ','_') %>
165
+ <%- else -%>
166
+ <%= a['type'].ljust(10) %> :<%= a['name'].tr('- ','_') %>
167
+ <%- end -%>
168
+ <%- end if m['arguments'] -%>
169
+ end
170
+
171
+ <%- end -%>
172
+ end
173
+
174
+ <%- end -%>
175
+ end
176
+ end
177
+ ].gsub!(/^ /,''), nil, '>-%').result(binding)
@@ -5,76 +5,34 @@ $:.unshift File.expand_path(File.dirname(__FILE__))
5
5
  require file
6
6
  end
7
7
 
8
- # AMQP protocol and transport
9
- %w[spec protocol buffer frame].each do |file|
10
- require 'engineroom/' + file
11
- end
8
+ require 'bunny/client'
9
+ require 'bunny/exchange'
10
+ require 'bunny/queue'
12
11
 
13
- # Bunny API
14
- %w[client exchange header queue].each do |file|
15
- require 'bunny/' + file
16
- end
12
+ require 'bunny/protocol/spec'
13
+ require 'bunny/protocol/protocol'
17
14
 
18
- # Error and return message definitions
19
- require 'api_messages'
15
+ require 'bunny/transport/buffer'
16
+ require 'bunny/transport/frame'
20
17
 
21
- class Bunny
18
+ module Bunny
19
+
22
20
  include Protocol
23
21
  include Transport
24
- include API
25
22
 
26
- attr_reader :client
27
-
28
- def initialize(opts = {})
29
- @client = API::Client.new(opts)
30
- end
31
-
32
- def logging=(bool)
33
- client.logging = bool
34
- end
23
+ class ProtocolError < StandardError; end
24
+ class ServerDownError < StandardError; end
25
+ class BufferOverflowError < StandardError; end
26
+ class InvalidTypeError < StandardError; end
27
+ class ConnectionError < StandardError; end
28
+ class MessageError < StandardError; end
35
29
 
36
- def logging
37
- client.logging
38
- end
39
-
40
- def start
41
- client.start_session
42
- end
43
-
44
- def status
45
- client.status
46
- end
30
+ VERSION = '0.3.0'
47
31
 
48
- def exchange(name, opts = {})
49
- client.exchanges[name] ||= API::Exchange.new(client, name, opts)
50
- end
51
-
52
- def queue(name, opts = {})
53
- client.queues[name] ||= API::Queue.new(client, name, opts)
54
- end
55
-
56
- def stop
57
- client.close
58
- end
59
-
60
- def queues
61
- client.queues ||= {}
62
- end
32
+ # Returns the Bunny version number
63
33
 
64
- def exchanges
65
- client.exchanges ||= {}
66
- end
67
-
68
- def host
69
- client.host
70
- end
71
-
72
- def vhost
73
- client.vhost
74
- end
75
-
76
- def port
77
- client.port
34
+ def self.version
35
+ VERSION
78
36
  end
79
-
37
+
80
38
  end