bunny_events 0.2.2 → 0.3.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.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/Gemfile.lock +19 -1
- data/README.md +89 -8
- data/bin/example +21 -3
- data/{message_queue_event.gemspec → bunny_events.gemspec} +1 -0
- data/lib/bunny_event.rb +1 -0
- data/lib/bunny_events/version.rb +1 -1
- data/lib/bunny_events.rb +39 -13
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 985592caa9bd8cc75584a5b75fd9867a46ed0335dbf5f40e488ceac4e1f1cf77
|
|
4
|
+
data.tar.gz: 349a76a616f41608a04f90cc33b5d5ed470712844347ef4797e110c5d138b576
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c48c7c19a3862fa90f21282db47273328e9355066dcb405bfa63c1b10ea3d3bd0595c6daee5a17cf44cfcda8d0c31b66354121348ec05c0682ec22765327416
|
|
7
|
+
data.tar.gz: 1c2b972049aa3e951bce82a13cdffde5a501525cfeeb8b031959dbecd03f24817a09ab4069581d52a269836f3ff5105e5b42623b09257e2390b1f3f3424b4232
|
data/Gemfile
CHANGED
|
@@ -2,8 +2,8 @@ source "https://rubygems.org"
|
|
|
2
2
|
|
|
3
3
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
|
4
4
|
|
|
5
|
-
# Specify your gem's dependencies in message_queue_event.gemspec
|
|
6
5
|
gemspec
|
|
7
6
|
|
|
8
7
|
gem "bunny", ">= 2.14.0"
|
|
9
|
-
gem 'bunny-mock'
|
|
8
|
+
gem 'bunny-mock'
|
|
9
|
+
gem 'coveralls', require: false
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
bunny_events (0.
|
|
4
|
+
bunny_events (0.2.2)
|
|
5
5
|
bunny (>= 2.14.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -12,7 +12,15 @@ GEM
|
|
|
12
12
|
amq-protocol (~> 2.3, >= 2.3.0)
|
|
13
13
|
bunny-mock (1.7.0)
|
|
14
14
|
bunny (>= 1.7)
|
|
15
|
+
coveralls (0.8.23)
|
|
16
|
+
json (>= 1.8, < 3)
|
|
17
|
+
simplecov (~> 0.16.1)
|
|
18
|
+
term-ansicolor (~> 1.3)
|
|
19
|
+
thor (>= 0.19.4, < 2.0)
|
|
20
|
+
tins (~> 1.6)
|
|
15
21
|
diff-lcs (1.3)
|
|
22
|
+
docile (1.3.2)
|
|
23
|
+
json (2.2.0)
|
|
16
24
|
rake (10.5.0)
|
|
17
25
|
rspec (3.8.0)
|
|
18
26
|
rspec-core (~> 3.8.0)
|
|
@@ -27,6 +35,15 @@ GEM
|
|
|
27
35
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
28
36
|
rspec-support (~> 3.8.0)
|
|
29
37
|
rspec-support (3.8.2)
|
|
38
|
+
simplecov (0.16.1)
|
|
39
|
+
docile (~> 1.1)
|
|
40
|
+
json (>= 1.8, < 3)
|
|
41
|
+
simplecov-html (~> 0.10.0)
|
|
42
|
+
simplecov-html (0.10.2)
|
|
43
|
+
term-ansicolor (1.7.1)
|
|
44
|
+
tins (~> 1.0)
|
|
45
|
+
thor (0.20.3)
|
|
46
|
+
tins (1.21.1)
|
|
30
47
|
|
|
31
48
|
PLATFORMS
|
|
32
49
|
ruby
|
|
@@ -36,6 +53,7 @@ DEPENDENCIES
|
|
|
36
53
|
bunny (>= 2.14.0)
|
|
37
54
|
bunny-mock
|
|
38
55
|
bunny_events!
|
|
56
|
+
coveralls
|
|
39
57
|
rake (~> 10.0)
|
|
40
58
|
rspec (~> 3.0)
|
|
41
59
|
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Bunny Events
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/bunny_events)
|
|
3
|
+
[](https://badge.fury.io/rb/bunny_events) [](https://travis-ci.org/Nexus-Mods/bunny_events) [](https://coveralls.io/github/Nexus-Mods/bunny_events?branch=master)
|
|
4
4
|
|
|
5
5
|
A simple wrapper gem to aid with producing events to a message queue, using Bunny, in a standardized and uniform way across multiple microservices.
|
|
6
6
|
|
|
7
|
-
Rather than
|
|
7
|
+
Rather than using Bunny directly, this gem allows an application to define "Event Definitions" which can be defined and published
|
|
8
8
|
in a modular way. This ensures that when you are producing a message, your application logic shouldn't care about how the
|
|
9
9
|
message is produced (E.g. your controller shouldn't care or know anything about what exchange to publish a message to, only the BunnyEvent
|
|
10
10
|
that has been defined cares)
|
|
@@ -14,6 +14,7 @@ Current Features and limitation:
|
|
|
14
14
|
- Allows a bunny connection to initialise the system
|
|
15
15
|
- Allows the definition of abstract events to be used application-wide
|
|
16
16
|
- Customization of exchange and queue options when producing an event
|
|
17
|
+
- By default, only initialises the exchange and queues on the first publish. This can be overriden with `opts[:always_create_when_publishing]`
|
|
17
18
|
|
|
18
19
|
## Installation
|
|
19
20
|
|
|
@@ -30,6 +31,52 @@ And then execute:
|
|
|
30
31
|
Or install it yourself as:
|
|
31
32
|
|
|
32
33
|
$ gem install bunny_events
|
|
34
|
+
|
|
35
|
+
### Rails Installation
|
|
36
|
+
To initialise the system with Rails, create a new intiailizer:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
# config/initializers/bunny-events.rb
|
|
40
|
+
if !Rails.env.test?
|
|
41
|
+
$BUNNY_EVENTS = BunnyEvents.new
|
|
42
|
+
$BUNNY_EVENTS.init Bunny.new("amqp://rabbitmq:rabbitmq@rabbit1:5672").start
|
|
43
|
+
end
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Events can then be created in app/events:
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
require 'bunny_event'
|
|
50
|
+
|
|
51
|
+
class MyTestEvent
|
|
52
|
+
include BunnyEvent
|
|
53
|
+
|
|
54
|
+
# define the event options for queueing this event. Each event type can have different options.
|
|
55
|
+
event_options :exchange => "test_exchange",
|
|
56
|
+
:exchange_opts => {
|
|
57
|
+
:type => :fanout
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# We can define what the message payload looks like here.
|
|
61
|
+
def initialize(msg)
|
|
62
|
+
@message = "My test message is #{msg}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Rails Testing
|
|
68
|
+
|
|
69
|
+
To use Bunny Events in tests, you can initialize a new instance of the system before every test (or just a single test) with BunnyMock
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
before(:each) do
|
|
73
|
+
@mock = BunnyMock.new.start
|
|
74
|
+
$BUNNY_EVENTS = BunnyEvents.new
|
|
75
|
+
$BUNNY_EVENTS.init @mock
|
|
76
|
+
end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Note: This requires the `bunny-mock` gem to be installed in your test environment
|
|
33
80
|
|
|
34
81
|
## Usage
|
|
35
82
|
|
|
@@ -38,12 +85,24 @@ Or install it yourself as:
|
|
|
38
85
|
To produce an event to the message queue, we must first define an event. In `app/events/my_test_event.rb`
|
|
39
86
|
|
|
40
87
|
```ruby
|
|
88
|
+
require 'bunny_event'
|
|
41
89
|
class MyTestEvent
|
|
42
90
|
include BunnyEvent
|
|
43
91
|
|
|
44
92
|
# define the event options for queueing this event. Each event type can have different options.
|
|
45
93
|
event_options :exchange => "test_exchange",
|
|
46
|
-
:
|
|
94
|
+
:exchange_opts => {
|
|
95
|
+
:type => :fanout
|
|
96
|
+
},
|
|
97
|
+
:queues =>
|
|
98
|
+
{
|
|
99
|
+
:some_queue => {
|
|
100
|
+
:opts => {
|
|
101
|
+
:durable => true
|
|
102
|
+
},
|
|
103
|
+
:routing_key => ""
|
|
104
|
+
}
|
|
105
|
+
}
|
|
47
106
|
|
|
48
107
|
# We can define what the message payload looks like here.
|
|
49
108
|
def initialize(msg)
|
|
@@ -79,15 +138,37 @@ Publishing the event requires the use of the BunnyEvents class
|
|
|
79
138
|
event = MyTestEvent.new "This is a test event"
|
|
80
139
|
|
|
81
140
|
# Use the BunnyEvents system to publish this event
|
|
82
|
-
BunnyEvents.
|
|
141
|
+
bunny_events = BunnyEvents.new
|
|
142
|
+
bunny_events.init Bunny.new("amqp://rabbitmq:rabbitmq@rabbit1:5672").start
|
|
143
|
+
bunny_events.publish event
|
|
83
144
|
```
|
|
84
145
|
|
|
85
|
-
|
|
146
|
+
When publishing, a custom routing key can also be used
|
|
86
147
|
|
|
87
148
|
```ruby
|
|
149
|
+
bunny_events.publish event, "some_routing_key"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Configuration
|
|
153
|
+
|
|
154
|
+
When defining an event, many options can be set via the event_options class method.
|
|
88
155
|
|
|
156
|
+
- `exchange` - Name of the exchange this event will publish it's messages to
|
|
157
|
+
- `exchange_opts` - Bunny-specific options for creating an exchange. See http://rubybunny.info/articles/exchanges.html for more information.
|
|
158
|
+
- `queues` - A hash of queues to be created and bound to the exchange. Each key consists of the name of the queue and the value is another hash, with the following options:
|
|
159
|
+
- `opts` - Bunny-specific options fo creating a queue
|
|
160
|
+
- `routing_key` - Key used for binding this queue to the exchange
|
|
161
|
+
- `ignore_bind` - Can be used to override the binding. Defaults to `false`. If true, will not bind this queue to the exchange. Is useful when utilising the default exchange.
|
|
162
|
+
- `always_create_when_publishing` - Overrides the queue/exchange creation process to run every time a message is processed. Default: `false`
|
|
163
|
+
- `routing_key` - The default routing key used for all messages pushed for this event. Can be changed when publishing a message E.g. ```bunny_events.publish event, "custom_routing_key"```
|
|
164
|
+
|
|
165
|
+
### Full example with initialisation
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
require 'bunny_event'
|
|
89
169
|
# This is done once as part of the configuration step, usually in a rails initializer, or at the start of your application
|
|
90
|
-
BunnyEvents.
|
|
170
|
+
bunny_events = BunnyEvents.new
|
|
171
|
+
bunny_events.init Bunny.new("amqp://rabbitmq:rabbitmq@rabbit1:5672").start
|
|
91
172
|
|
|
92
173
|
# Event definitions are defined in classes, in rails, we generally use app/messages
|
|
93
174
|
class MyTestEvent
|
|
@@ -116,7 +197,7 @@ end
|
|
|
116
197
|
|
|
117
198
|
# When we want to create a new instance of an event, we create and publish the object
|
|
118
199
|
event = MyTestEvent.new "test"
|
|
119
|
-
|
|
200
|
+
bunny_events.publish event
|
|
120
201
|
```
|
|
121
202
|
|
|
122
203
|
## Development
|
|
@@ -127,7 +208,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
127
208
|
|
|
128
209
|
## Contributing
|
|
129
210
|
|
|
130
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/Nexus-Mods/
|
|
211
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Nexus-Mods/bunny_events
|
|
131
212
|
|
|
132
213
|
## License
|
|
133
214
|
|
data/bin/example
CHANGED
|
@@ -17,7 +17,7 @@ class DummyEvent
|
|
|
17
17
|
|
|
18
18
|
event_options :exchange => "test_exchange",
|
|
19
19
|
:exchange_opts => {
|
|
20
|
-
:type => :
|
|
20
|
+
:type => :direct
|
|
21
21
|
},
|
|
22
22
|
:queues =>
|
|
23
23
|
{
|
|
@@ -29,6 +29,7 @@ class DummyEvent
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
|
|
32
33
|
def initialize(msg)
|
|
33
34
|
@message = "My test message is #{msg}"
|
|
34
35
|
end
|
|
@@ -36,7 +37,24 @@ class DummyEvent
|
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
p "Publishing event"
|
|
40
|
+
|
|
39
41
|
bunny_events = BunnyEvents.new
|
|
40
|
-
|
|
42
|
+
bunny = Bunny.new("amqp://rabbitmq:rabbitmq@localhost:5672").start
|
|
43
|
+
bunny_events.init bunny
|
|
44
|
+
|
|
45
|
+
bunny_events.publish DummyEvent.new "test"
|
|
46
|
+
|
|
47
|
+
p "deleting exchane"
|
|
48
|
+
p bunny.exchange_exists? "test_exchange"
|
|
49
|
+
|
|
50
|
+
x = bunny_events.channels["DummyEvent"].exchange "test_exchange"
|
|
51
|
+
x.delete
|
|
52
|
+
|
|
53
|
+
p "Does exchange exist?"
|
|
54
|
+
p bunny.exchange_exists? "test_exchange"
|
|
55
|
+
|
|
56
|
+
bunny_events.publish DummyEvent.new "test"
|
|
57
|
+
|
|
58
|
+
p bunny.exchange_exists? "test_exchange"
|
|
41
59
|
|
|
42
|
-
|
|
60
|
+
p "end"
|
data/lib/bunny_event.rb
CHANGED
data/lib/bunny_events/version.rb
CHANGED
data/lib/bunny_events.rb
CHANGED
|
@@ -4,6 +4,10 @@ class BunnyEvents
|
|
|
4
4
|
|
|
5
5
|
attr_accessor :channels, :bunny_connection
|
|
6
6
|
|
|
7
|
+
# Keeps track of which events have been intiailized by this BunnyEvents worker. Used to ensure that the queue and
|
|
8
|
+
# exchange creation is only performed once.
|
|
9
|
+
attr_accessor :initialized_events
|
|
10
|
+
|
|
7
11
|
@@defaults = {
|
|
8
12
|
:exchange => "",
|
|
9
13
|
:exchange_type => :direct,
|
|
@@ -27,6 +31,8 @@ class BunnyEvents
|
|
|
27
31
|
|
|
28
32
|
@channels = {}
|
|
29
33
|
|
|
34
|
+
@initialized_exchanges = {}
|
|
35
|
+
|
|
30
36
|
@bunny_connection = bunny_connection
|
|
31
37
|
|
|
32
38
|
end
|
|
@@ -36,14 +42,14 @@ class BunnyEvents
|
|
|
36
42
|
end
|
|
37
43
|
|
|
38
44
|
# Public message. message should be an instance of BaseMessage (or a class with BaseMessage included)
|
|
39
|
-
def publish(message)
|
|
45
|
+
def publish(message, routing_key = nil)
|
|
40
46
|
|
|
41
47
|
unless message.class.included_modules.include?(BunnyEvent)
|
|
42
48
|
raise Exceptions::InvalidBunnyEvent.new
|
|
43
49
|
end
|
|
44
50
|
|
|
45
51
|
unless connected?
|
|
46
|
-
|
|
52
|
+
raise Exceptions::InvalidBunnyConnection.new
|
|
47
53
|
end
|
|
48
54
|
|
|
49
55
|
# get the options defined by the message queue event class
|
|
@@ -56,28 +62,48 @@ class BunnyEvents
|
|
|
56
62
|
|
|
57
63
|
channel = @channels[message.class.name]
|
|
58
64
|
|
|
59
|
-
#
|
|
60
|
-
if
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
# Ensure that the exchange, queue and binding creation is only performed once
|
|
66
|
+
if (!@initialized_exchanges.key?(message.class.name)) || opts[:always_create_when_publishing]
|
|
67
|
+
# If the event was sent with an exchange name, create and submit this to the exchange, otherwise, just use the default exchange
|
|
68
|
+
if !opts[:exchange].nil? && !opts[:exchange].empty?
|
|
69
|
+
x = channel.exchange(opts[:exchange], opts[:exchange_opts] || {})
|
|
70
|
+
else
|
|
71
|
+
x = channel.default_exchange
|
|
72
|
+
end
|
|
73
|
+
# if the event was sent with queue definitions, ensure to create the bindings
|
|
74
|
+
if !opts[:queues].nil?
|
|
75
|
+
handle_queue_definitions channel, x, opts[:queues]
|
|
76
|
+
end
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
handle_queue_definitions channel, x, opts[:queues]
|
|
78
|
+
# ensure this event's creation params are not processed again
|
|
79
|
+
@initialized_exchanges[message.class.name] ||= x
|
|
69
80
|
end
|
|
70
81
|
|
|
71
|
-
x
|
|
82
|
+
x ||= @initialized_exchanges[message.class.name]
|
|
72
83
|
|
|
84
|
+
# ensure exchange is not null
|
|
85
|
+
if x.nil? || !@bunny_connection.exchange_exists?(opts[:exchange])
|
|
86
|
+
raise Exceptions::InvalidExchange.new
|
|
73
87
|
end
|
|
74
88
|
|
|
89
|
+
# publish message along with the optional routing key
|
|
90
|
+
x.publish message.message, :routing_key => routing_key || opts[:routing_key]
|
|
91
|
+
end
|
|
92
|
+
|
|
75
93
|
private
|
|
76
94
|
def handle_queue_definitions (channel, exchange, queues)
|
|
77
95
|
queues.each do |q, opts|
|
|
78
96
|
# Create this queue and bind, if the binding options are present
|
|
79
97
|
queue = channel.queue q.to_s, opts[:opts] || {}
|
|
80
|
-
|
|
98
|
+
|
|
99
|
+
# if ignore bind isn't set, set to nil
|
|
100
|
+
ignore_bind = opts[:ignore_bind] || false
|
|
101
|
+
|
|
102
|
+
# if we aren't ignoring the binding for this queue, check if it's already bound. We also shouldn't bind directly
|
|
103
|
+
# to the default queue
|
|
104
|
+
if !ignore_bind && !queue.bound_to?(exchange) && exchange.name != ""
|
|
105
|
+
queue.bind exchange, :key => opts[:routing_key] || ""
|
|
106
|
+
end
|
|
81
107
|
end
|
|
82
108
|
end
|
|
83
109
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bunny_events
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dean Lovett
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-09-
|
|
11
|
+
date: 2019-09-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bunny
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '3.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: bunny-mock
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
69
83
|
description: This gem allows the use of "Messages" to be defined and published very
|
|
70
84
|
easily, without your models/controllers having to worry about how messages are produced.
|
|
71
85
|
Supports AMQP
|
|
@@ -86,10 +100,10 @@ files:
|
|
|
86
100
|
- bin/console
|
|
87
101
|
- bin/example
|
|
88
102
|
- bin/setup
|
|
103
|
+
- bunny_events.gemspec
|
|
89
104
|
- lib/bunny_event.rb
|
|
90
105
|
- lib/bunny_events.rb
|
|
91
106
|
- lib/bunny_events/version.rb
|
|
92
|
-
- message_queue_event.gemspec
|
|
93
107
|
homepage: https://www.nexusmods.com
|
|
94
108
|
licenses:
|
|
95
109
|
- MIT
|