liebre 0.1.3

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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +51 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +47 -0
  5. data/LICENSE +22 -0
  6. data/README.md +268 -0
  7. data/lib/liebre.rb +24 -0
  8. data/lib/liebre/common.rb +7 -0
  9. data/lib/liebre/common/utils.rb +24 -0
  10. data/lib/liebre/config.rb +48 -0
  11. data/lib/liebre/connection_manager.rb +64 -0
  12. data/lib/liebre/publisher.rb +88 -0
  13. data/lib/liebre/runner.rb +59 -0
  14. data/lib/liebre/runner/consumers.rb +36 -0
  15. data/lib/liebre/runner/starter.rb +40 -0
  16. data/lib/liebre/runner/starter/consumer.rb +91 -0
  17. data/lib/liebre/runner/starter/consumer/handler.rb +35 -0
  18. data/lib/liebre/runner/starter/resources.rb +39 -0
  19. data/lib/liebre/runner/starter/resources/queue_builder.rb +58 -0
  20. data/lib/liebre/runner/starter/rpc.rb +45 -0
  21. data/lib/liebre/tasks.rb +12 -0
  22. data/lib/liebre/version.rb +5 -0
  23. data/liebre.gemspec +26 -0
  24. data/spec/config/liebre.yml +47 -0
  25. data/spec/config/rabbitmq.yml +35 -0
  26. data/spec/integration_spec.rb +73 -0
  27. data/spec/liebre/config_spec.rb +62 -0
  28. data/spec/liebre/connection_manager_spec.rb +40 -0
  29. data/spec/liebre/publisher_spec.rb +86 -0
  30. data/spec/liebre/runner/consumers_spec.rb +59 -0
  31. data/spec/liebre/runner/starter/consumer_spec.rb +140 -0
  32. data/spec/liebre/runner/starter/resources/queue_builder_spec.rb +69 -0
  33. data/spec/liebre/runner/starter/resources_spec.rb +36 -0
  34. data/spec/liebre/runner/starter/rpc_spec.rb +92 -0
  35. data/spec/liebre/runner/starter_spec.rb +59 -0
  36. data/spec/liebre/runner_spec.rb +50 -0
  37. data/spec/spec_helper.rb +23 -0
  38. metadata +172 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cea30bec0897de16f0f5c622dfc40dd4918e10a4
4
+ data.tar.gz: 129b44949789081686fd1331701bca94c1a498b5
5
+ SHA512:
6
+ metadata.gz: fb2469f49b0b8583ce5b73fb20c6396b4791d395d2ad2dfc7f8d9486d8bc675a7dc2b666fe16cd5950d709bc05cf7cc1f0d9da24b6fe2eced3ef92ad71227d4d
7
+ data.tar.gz: ec76d7163561e469037e61b12ab3f2c35968fec5217b756119729e51981692fe7dc691a2d80f0c7e4d0ab1da6f5c5d3668936226cd315e7644ec7b087b4588ae
data/.gitignore ADDED
@@ -0,0 +1,51 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ .ruby-version
47
+ .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+ /nbproject
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in liebre.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ liebre (0.1.2)
5
+ bunny (~> 2.5, >= 2.5.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ amq-protocol (2.0.1)
11
+ bunny (2.5.1)
12
+ amq-protocol (>= 2.0.1)
13
+ coderay (1.1.1)
14
+ diff-lcs (1.2.5)
15
+ method_source (0.8.2)
16
+ pry (0.10.4)
17
+ coderay (~> 1.1.0)
18
+ method_source (~> 0.8.1)
19
+ slop (~> 3.4)
20
+ rake (11.2.2)
21
+ rspec (3.5.0)
22
+ rspec-core (~> 3.5.0)
23
+ rspec-expectations (~> 3.5.0)
24
+ rspec-mocks (~> 3.5.0)
25
+ rspec-core (3.5.2)
26
+ rspec-support (~> 3.5.0)
27
+ rspec-expectations (3.5.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.5.0)
30
+ rspec-mocks (3.5.0)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.5.0)
33
+ rspec-support (3.5.0)
34
+ slop (3.6.0)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ bundler (~> 1.6)
41
+ liebre!
42
+ pry
43
+ rake
44
+ rspec
45
+
46
+ BUNDLED WITH
47
+ 1.12.5
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 jcabotc
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,268 @@
1
+ # Liebre
2
+
3
+ ## Intro
4
+
5
+ **Liebre stands for hare in spanish.**
6
+
7
+ This is a gem that handles RabbitMQ consumers, publishers and RPCs, based on [bunny](https://github.com/ruby-amqp/bunny).
8
+
9
+ * It allows to create classes that will be invoked everytime a message it's received in its subscribed queue.
10
+ * It handles RPCs as a special Consumer where a callback message is returned to the exchange.
11
+ * You can use its Publisher to send message to an exchange.
12
+ * There is also a Publisher RPC method to send a message and wait for its response.
13
+
14
+ ## Configuration
15
+ It is based on 2 config files:
16
+
17
+ * rabbitmq.yml: it contains RabbitMQ connection configurations and can be enviroment dependant (default path `config/rabbitmq.yml`), it must contain, at least the `default` connection
18
+ * without environment set:
19
+ ```
20
+ default:
21
+ :host: localhost
22
+ :port: 5672
23
+ :user: guest
24
+ :pass: guest
25
+ :vhost: /
26
+ :threaded: true
27
+ :heartbeat: 2
28
+ ```
29
+ * with environment set:
30
+ ```
31
+ development:
32
+ default:
33
+ :host: localhost
34
+ :port: 5672
35
+ :user: guest
36
+ :pass: guest
37
+ :vhost: /
38
+ :threaded: true
39
+ :heartbeat: 2
40
+ rpc:
41
+ :host: localhost
42
+ :port: 5672
43
+ :user: guest
44
+ :pass: guest
45
+ :vhost: rpc
46
+ :threaded: true
47
+ :heartbeat: 2
48
+ test:
49
+ default:
50
+ :host: localhost
51
+ :port: 5672
52
+ :user: guest
53
+ :pass: guest
54
+ :vhost: /
55
+ :threaded: true
56
+ :heartbeat: 2
57
+ rpc:
58
+ :host: localhost
59
+ :port: 5672
60
+ :user: guest
61
+ :pass: guest
62
+ :vhost: rpc
63
+ :threaded: true
64
+ :heartbeat: 2
65
+
66
+ production:
67
+ ...
68
+ ```
69
+
70
+ * liebre.yml (default path `config/liebre.yml`)
71
+ ```
72
+ rpc_request_timeout: 5
73
+
74
+ consumers:
75
+ some_consumer:
76
+ class_name: MyConsumer
77
+ rpc: false
78
+ pool_size: 1
79
+ num_threads: 4
80
+ exchange:
81
+ name: "consumer_exchange"
82
+ type: "fanout"
83
+ opts:
84
+ durable: false
85
+ queue:
86
+ name: "consumer_queue"
87
+ opts:
88
+ durable: false
89
+ bind:
90
+ routing_key: #key a string or an array of strings
91
+ - key_1
92
+ - key_2
93
+
94
+ some_rpc:
95
+ class_name: MyRPC
96
+ rpc: true
97
+ connection_name: rpc
98
+ pool_size: 1
99
+ exchange:
100
+ name: "rpc_exchange"
101
+ type: "fanout"
102
+ opts:
103
+ durable: false
104
+ queue:
105
+ name: "rpc_queue"
106
+ opts:
107
+ durable: false
108
+
109
+ publishers:
110
+ some_publisher:
111
+ exchange:
112
+ name: "consumer_exchange"
113
+ type: "fanout"
114
+ opts:
115
+ durable: false
116
+ rpc_publisher:
117
+ connection_name: rpc
118
+ exchange:
119
+ name: "rpc_exchange"
120
+ type: "fanout"
121
+ opts:
122
+ durable: false
123
+ ```
124
+
125
+ ### Consumers
126
+
127
+ An entry for each consumer in your app, consumer options:
128
+ * `class_name` (mandatory): The class that will be invoked everytime a message is received
129
+ * `rpc` is a flag to specify the consumer behaviour (default false)
130
+ * `connection_name`: the name of the connection to use (default `default`)
131
+ * `pool_size` of the connection channel (default 1)
132
+ * `num_threads`: number of consumers of the queue (default 1)
133
+ * `exchange` a hash of options:
134
+ * `name`: the exchange name
135
+ * `type`: the exchange type (fanout, direct or topic)
136
+ * `opts`: options hash to pass to bunny exchange function
137
+ * `queue` a hash of options:
138
+ * `name`: the queue name
139
+ * `opts`: options hash to pass to bunny queue function
140
+ * `bind` a hash of options (optional):
141
+ * `routing_key`: the binding routing key, it can be a single string or an array of strings
142
+
143
+ ### Publishers
144
+
145
+ An entry for each exchange you want to publish to, options:
146
+ * `connection_name`: the name of the connection to use (default `default`)
147
+ * `exchange` a hash of options:
148
+ * `name`: the exchange name
149
+ * `type`: the exchange type (fanout, direct or topic)
150
+ * `opts`: options hash to pass to bunny exchange function
151
+
152
+ ### Other configurations
153
+
154
+ `rpc_request_timeout`: set the timeout for an RPC request
155
+
156
+ ### Change default paths and set env and Logger
157
+
158
+ You can change these defaults in an initializer with something like:
159
+
160
+ ```
161
+ Liebre::Config.config_path = "your/custom/path"
162
+ Liebre::Config.connection_path = "your/custom/path"
163
+
164
+ Liebre::Config.env = "production"
165
+ Liebre::Config.logger = Logger.new(...)
166
+
167
+ ```
168
+
169
+ ## Usage
170
+
171
+ There are 2 different consumer usages: `Consumer` and `RPC`.
172
+
173
+ ### Consumer
174
+
175
+ You only need to create a class with this simple interface:
176
+
177
+ ```
178
+ class MyConsumer
179
+
180
+ def initialize payload, meta
181
+ @payload = payload #the content of the message
182
+ @meta = meta #the meta information (also called properties)
183
+ end
184
+
185
+ def call
186
+ #do your stuff here
187
+ #return :ack to anknowledge the message,
188
+ #return :reject to requeue it
189
+ #or return :error to send it to the dead-letter-exchange
190
+ :ack
191
+ end
192
+
193
+ end
194
+ ```
195
+
196
+ Every time a message is received, a new instance of this class will be created.
197
+
198
+ ### RPC
199
+
200
+ You only need to create a class with this simple interface:
201
+
202
+ ```
203
+ class MyRPC
204
+
205
+ def initialize payload, meta, callback
206
+ @payload = payload #the content of the message
207
+ @meta = meta #the meta information (also called properties)
208
+ @callback = callback #a Proc that will publish an answer
209
+ end
210
+
211
+ def call
212
+ #do your stuff here
213
+ @callback.call("your response")
214
+ end
215
+
216
+ end
217
+ ```
218
+
219
+ Every time a message is received, a new instance of this class will be created.
220
+
221
+ There are 2 ways to publish a message: `enqueue` and `enqueue_and_wait`.
222
+
223
+ ### `enqueue`
224
+
225
+ ```
226
+ publisher = Liebre::Publisher.new("some_publisher_name")
227
+
228
+ publisher.enqueue "hello", :routing_key => "consumer_queue"
229
+
230
+ publisher.enqueue "bye", :routing_key => "consumer_queue"
231
+
232
+ ```
233
+
234
+ ### `enqueue_and_wait` (alias `rpc`)
235
+
236
+ ```
237
+ rpc_publisher = Liebre::Publisher.new("rpc_publisher")
238
+
239
+ response = publisher.enqueue_and_wait "hello", :routing_key => "consumer_queue"
240
+
241
+ another_response = publisher.rpc "bye", :routing_key => "consumer_queue"
242
+
243
+ ```
244
+
245
+ ### Installation and Execution
246
+
247
+ Add the following to your Gemfile:
248
+ ```
249
+ gem "liebre", ">~ 0.1"
250
+ ```
251
+
252
+ In your Raketask add:
253
+
254
+ ```
255
+ require "liebre/tasks"
256
+ ```
257
+
258
+ Then you just need to run:
259
+ ```
260
+ rake liebre:run
261
+ ```
262
+
263
+ Alternative way:
264
+ ```
265
+ require 'liebre'
266
+
267
+ Liebre::Runner.new.start
268
+ ```
data/lib/liebre.rb ADDED
@@ -0,0 +1,24 @@
1
+ require "liebre/version"
2
+ require "bunny"
3
+
4
+ module Liebre
5
+
6
+ autoload :Common, 'liebre/common'
7
+ autoload :Config, 'liebre/config'
8
+ autoload :ConnectionManager, 'liebre/connection_manager'
9
+ autoload :Publisher, 'liebre/publisher'
10
+ autoload :Runner, 'liebre/runner'
11
+
12
+ def self.config
13
+ @config ||= Config.new
14
+ end
15
+
16
+ def self.env
17
+ Config.env
18
+ end
19
+
20
+ def self.logger
21
+ Config.logger
22
+ end
23
+
24
+ end
@@ -0,0 +1,7 @@
1
+ module Liebre
2
+ module Common
3
+
4
+ autoload :Utils, 'liebre/common/utils'
5
+
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ module Liebre
2
+ module Common
3
+ module Utils
4
+ def self.create_exchange channel, config
5
+ exchange_name = config.fetch "name"
6
+
7
+ type = config.fetch("type")
8
+ opts = config.fetch("opts", {})
9
+ exchange_opts = symbolize_keys(opts.merge("type" => type))
10
+
11
+ channel.exchange exchange_name, exchange_opts
12
+ end
13
+
14
+ def self.symbolize_keys hash
15
+ result = {}
16
+ hash.each do |k, v|
17
+ result[k.to_sym] = v.is_a?(Hash) ? symbolize_keys(v) : v
18
+ end
19
+ result
20
+ end
21
+ end
22
+
23
+ end
24
+ end