jerryluk-rabbitmq-jruby-client 0.1.4 → 0.1.5
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/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
|