jerryluk-rabbitmq-jruby-client 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README +49 -22
- data/lib/rabbitmq_client.rb +33 -13
- data/spec/rabbitmq_client_spec.rb +50 -1
- metadata +1 -1
data/README
CHANGED
@@ -1,22 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
http://www.rabbitmq.com
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
RabbitMQ JRuby Client
|
2
|
+
=====================
|
3
|
+
rabbitmq-jruby-client allows you to use RabbitMQ Client from JRuby using the official Java RabbitMQ client from Rabbit Technologies
|
4
|
+
See more at http://www.rabbitmq.com
|
5
|
+
|
6
|
+
Getting Started
|
7
|
+
===============
|
8
|
+
1. Make sure you can install RubyGem from GitHub (you only have to do this once): jruby -S gem sources -a http://gems.github.com
|
9
|
+
2. Install and start RabbitMQ (see below)
|
10
|
+
3. Install JRuby RabbitMQ Client: jruby -S gem install jerryluk-rabbitmq-jruby-client
|
11
|
+
|
12
|
+
Example Usage
|
13
|
+
=============
|
14
|
+
gem 'jerryluk-rabbitmq-jruby-client'
|
15
|
+
require 'rabbitmq_client'
|
16
|
+
|
17
|
+
# Initializes the new client and connect to the server
|
18
|
+
client = RabbitMQClient.new
|
19
|
+
|
20
|
+
# Initializes a new queue
|
21
|
+
queue = client.queue('queue_name')
|
22
|
+
|
23
|
+
# Initializes a new exchange
|
24
|
+
exchange = client.exchange('exchange_name')
|
25
|
+
|
26
|
+
# Connects queue with the exchange
|
27
|
+
queue.bind(exchange)
|
28
|
+
|
29
|
+
# Publish a message to the queue
|
30
|
+
queue.publish('message body')
|
31
|
+
|
32
|
+
# Retrieve a message from the queue
|
33
|
+
message = queue.retrieve
|
34
|
+
|
35
|
+
# Subscribe to a queue with callback
|
36
|
+
queue.subscribe do |message|
|
37
|
+
# do something with message
|
38
|
+
end
|
39
|
+
|
40
|
+
Installing RabbitMQ on OS X
|
41
|
+
===========================
|
42
|
+
1. Install MacPorts
|
43
|
+
2. sudo port install erlang
|
44
|
+
3. wget http://www.rabbitmq.com/releases/rabbitmq-server/v1.5.3/rabbitmq-server-generic-unix-1.5.3.tar.gz
|
45
|
+
4. tar zxvf rabbitmq-server-1.5.3.tar.gz
|
46
|
+
5. sudo mv rabbitmq_server-1.5.3 /opt/local/lib/erlang/lib
|
47
|
+
|
48
|
+
To run RabbitMQ
|
49
|
+
6. sudo /opt/local/lib/erlang/lib/rabbitmq_server-1.5.3/sbin/rabbitmq-server
|
data/lib/rabbitmq_client.rb
CHANGED
@@ -12,8 +12,11 @@ class RabbitMQClient
|
|
12
12
|
include_class('com.rabbitmq.client.Channel')
|
13
13
|
include_class('com.rabbitmq.client.Consumer')
|
14
14
|
include_class('com.rabbitmq.client.DefaultConsumer')
|
15
|
+
include_class('com.rabbitmq.client.MessageProperties')
|
15
16
|
include_class('java.lang.String') { |package, name| "J#{name}" }
|
16
17
|
|
18
|
+
class RabbitMQClientError < StandardError;end
|
19
|
+
|
17
20
|
class QueueConsumer < DefaultConsumer
|
18
21
|
def initialize(channel, block)
|
19
22
|
@channel = channel
|
@@ -24,26 +27,36 @@ class RabbitMQClient
|
|
24
27
|
def handleDelivery(consumer_tag, envelope, properties, body)
|
25
28
|
delivery_tag = envelope.get_delivery_tag
|
26
29
|
message_body = Marshal.load(String.from_java_bytes(body))
|
30
|
+
# TODO: Do we need to do something with properties?
|
27
31
|
@block.call message_body
|
28
32
|
@channel.basic_ack(delivery_tag, false)
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
32
36
|
class Queue
|
33
|
-
def initialize(name, channel)
|
37
|
+
def initialize(name, channel, durable=false)
|
34
38
|
@name = name
|
39
|
+
@durable = durable
|
35
40
|
@channel = channel
|
36
|
-
@channel.queue_declare(name)
|
41
|
+
@channel.queue_declare(name, durable)
|
37
42
|
self
|
38
43
|
end
|
39
44
|
|
40
|
-
def bind(exchange, routing_key=
|
41
|
-
@routing_key = routing_key
|
45
|
+
def bind(exchange, routing_key='')
|
46
|
+
@routing_key = routing_key
|
42
47
|
@exchange = exchange
|
48
|
+
raise RabbitMQClientError, "queue and exchange has different durable property" unless @durable == exchange.durable
|
43
49
|
@channel.queue_bind(@name, @exchange.name, @routing_key)
|
44
50
|
self
|
45
51
|
end
|
46
52
|
|
53
|
+
# Set props for different type of message. Currently they are:
|
54
|
+
# RabbitMQClient::MessageProperties::MINIMAL_BASIC
|
55
|
+
# RabbitMQClient::MessageProperties::MINIMAL_PERSISTENT_BASIC
|
56
|
+
# RabbitMQClient::MessageProperties::BASIC
|
57
|
+
# RabbitMQClient::MessageProperties::PERSISTENT_BASIC
|
58
|
+
# RabbitMQClient::MessageProperties::TEXT_PLAIN
|
59
|
+
# RabbitMQClient::MessageProperties::PERSISTENT_TEXT_PLAIN
|
47
60
|
def publish(message_body, props=nil)
|
48
61
|
auto_bind
|
49
62
|
message_body_byte = Marshal.dump(message_body).to_java_bytes
|
@@ -51,6 +64,11 @@ class RabbitMQClient
|
|
51
64
|
message_body
|
52
65
|
end
|
53
66
|
|
67
|
+
def persistent_publish(message_body, props=MessageProperties::PERSISTENT_BASIC)
|
68
|
+
raise RabbitMQClientError, "can only publish persistent message to durable queue" unless @durable
|
69
|
+
publish(message_body, props)
|
70
|
+
end
|
71
|
+
|
54
72
|
def retrieve
|
55
73
|
auto_bind
|
56
74
|
message_body = nil
|
@@ -73,7 +91,7 @@ class RabbitMQClient
|
|
73
91
|
protected
|
74
92
|
def auto_bind
|
75
93
|
unless @exchange
|
76
|
-
exchange = Exchange.new("#{@name}_exchange", 'fanout', @channel)
|
94
|
+
exchange = Exchange.new("#{@name}_exchange", 'fanout', @channel, @durable)
|
77
95
|
self.bind(exchange)
|
78
96
|
end
|
79
97
|
end
|
@@ -81,12 +99,14 @@ class RabbitMQClient
|
|
81
99
|
|
82
100
|
class Exchange
|
83
101
|
attr_reader :name
|
102
|
+
attr_reader :durable
|
84
103
|
|
85
|
-
def initialize(name, type, channel)
|
104
|
+
def initialize(name, type, channel, durable=false)
|
86
105
|
@name = name
|
87
106
|
@type = type
|
107
|
+
@durable = durable
|
88
108
|
@channel = channel
|
89
|
-
@channel.exchange_declare(@name, type.to_s)
|
109
|
+
@channel.exchange_declare(@name, type.to_s, durable)
|
90
110
|
self
|
91
111
|
end
|
92
112
|
end
|
@@ -99,7 +119,7 @@ class RabbitMQClient
|
|
99
119
|
attr_reader :connection
|
100
120
|
|
101
121
|
# Instance Methods
|
102
|
-
def initialize(options={})
|
122
|
+
def initialize(options={:auto_connect => true})
|
103
123
|
# server address
|
104
124
|
@host = options[:host] || '127.0.0.1'
|
105
125
|
@port = options[:port] || 5672
|
@@ -113,7 +133,7 @@ class RabbitMQClient
|
|
113
133
|
@queues = {}
|
114
134
|
@exchanges = {}
|
115
135
|
|
116
|
-
connect
|
136
|
+
connect if options[:auto_connect]
|
117
137
|
# Disconnect before the object is destroyed
|
118
138
|
define_finalizer(self, lambda {|id| self.disconnect if self.connected? })
|
119
139
|
self
|
@@ -140,12 +160,12 @@ class RabbitMQClient
|
|
140
160
|
@connection != nil
|
141
161
|
end
|
142
162
|
|
143
|
-
def queue(name)
|
144
|
-
@queues[name] ||= Queue.new(name, @channel)
|
163
|
+
def queue(name, durable=false)
|
164
|
+
@queues[name] ||= Queue.new(name, @channel, durable)
|
145
165
|
end
|
146
166
|
|
147
|
-
def exchange(name, type='fanout')
|
148
|
-
@exchanges[name] ||= Exchange.new(name, type, @channel)
|
167
|
+
def exchange(name, type='fanout', durable=false)
|
168
|
+
@exchanges[name] ||= Exchange.new(name, type, @channel, durable)
|
149
169
|
end
|
150
170
|
end
|
151
171
|
|
@@ -7,6 +7,10 @@ describe RabbitMQClient do
|
|
7
7
|
@client = RabbitMQClient.new
|
8
8
|
end
|
9
9
|
|
10
|
+
after(:each) do
|
11
|
+
@client.disconnect
|
12
|
+
end
|
13
|
+
|
10
14
|
it "should able to create a connection" do
|
11
15
|
@client.connection.should_not be_nil
|
12
16
|
end
|
@@ -20,7 +24,7 @@ describe RabbitMQClient do
|
|
20
24
|
exchange.should_not be_nil
|
21
25
|
end
|
22
26
|
|
23
|
-
describe Queue do
|
27
|
+
describe Queue, "Basic non-persistent queue" do
|
24
28
|
before(:each) do
|
25
29
|
@queue = @client.queue('test_queue')
|
26
30
|
@exchange = @client.exchange('test_exchange', 'direct')
|
@@ -51,5 +55,50 @@ describe RabbitMQClient do
|
|
51
55
|
sleep 1
|
52
56
|
a.should == 3
|
53
57
|
end
|
58
|
+
|
59
|
+
it "should raise an exception if binding a persistent queue with non-persistent exchange and vice versa" do
|
60
|
+
persistent_queue = @client.queue('test_queue1', true)
|
61
|
+
persistent_exchange = @client.exchange('test_exchange1', 'fanout', true)
|
62
|
+
lambda { persistent_queue.bind(@exchange) }.should raise_error(RabbitMQClient::RabbitMQClientError)
|
63
|
+
lambda { @queue.bind(persistent_exchange) }.should raise_error(RabbitMQClient::RabbitMQClientError)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should raise an exception if publish a persistent message on non-duration queue" do
|
67
|
+
@queue.bind(@exchange)
|
68
|
+
lambda { @queue.persistent_publish('Hello') }.should raise_error(RabbitMQClient::RabbitMQClientError)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe Queue, "Basic persistent queue" do
|
73
|
+
before(:each) do
|
74
|
+
@queue = @client.queue('test_durable_queue', true)
|
75
|
+
@exchange = @client.exchange('test_durable_exchange', 'fanout', true)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should able to create a queue" do
|
79
|
+
@queue.should_not be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should able to bind to an exchange" do
|
83
|
+
@queue.bind(@exchange).should_not be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should able to publish and retrieve a message" do
|
87
|
+
@queue.bind(@exchange)
|
88
|
+
@queue.persistent_publish('Hello World')
|
89
|
+
@queue.retrieve.should == 'Hello World'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should able to subscribe with a callback function" do
|
93
|
+
a = 0
|
94
|
+
@queue.bind(@exchange)
|
95
|
+
@queue.subscribe do |v|
|
96
|
+
a += v.to_i
|
97
|
+
end
|
98
|
+
@queue.persistent_publish("1")
|
99
|
+
@queue.persistent_publish("2")
|
100
|
+
sleep 1
|
101
|
+
a.should == 3
|
102
|
+
end
|
54
103
|
end
|
55
104
|
end
|