hutch 0.18.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae290b72e28ca5ca72f8014fe5688e35b4c31716
4
- data.tar.gz: 2a817eece4ab761d6558255395e123d5cea19ea0
3
+ metadata.gz: c5b96423188a88e607bf694005618e1c13bc6ce1
4
+ data.tar.gz: 97955f0060eea500cbd6cc49c3c393adccfaf8a6
5
5
  SHA512:
6
- metadata.gz: b929abefa84452c0b5a74fc2dcfc5f2918fb752d80f97b77e97cf4d0fbfad99e119cd09f3251f17edf1450ee7ccc063a76efaa9e31d318526aabf5a147779b84
7
- data.tar.gz: c5c04b649c3ea2333ff86273d7d17a1d843a02e782bd981d19ef2ea4025286761b4b96fd8200026ce2f503108d588c0aa61f204997632f02ac467ac5fa4633c3
6
+ metadata.gz: d161d2cf60136e26356a18f7a6f552fd11361bce6258132ce9dc807d219290f1fa67fda7f801fb58cacd542c224a93b4941c473aaa4c5ee3b43446632ab03c96
7
+ data.tar.gz: 7d2c9d3f0524a9583e76c853823a1527a9d516d7a2cf368aa061412442930e09d5a2b7855c915d4ab3e1ca8c39b2a82f0a864a6e51d558a420e1a9efd3d96cc1
@@ -1,4 +1,29 @@
1
- ## 0.18.0 — (unreleased)
1
+ ## 0.19.0 — (unreleased)
2
+
3
+ ### Pluggable Serialisers
4
+
5
+ Hutch now supports pluggable serialisers: see `Hutch::Serializer::JSON` for
6
+ an example. Serialiser is configured via Hutch config as a Ruby
7
+ class.
8
+
9
+ Contributed by Dmitry Galinsky.
10
+
11
+
12
+ ### multi_json Update
13
+
14
+ Hutch now depends on multi_json `1.11.x`.
15
+
16
+ ### Bunny Update
17
+
18
+ Bunny is updated to [2.2.0](http://blog.rubyrabbitmq.info/blog/2015/09/06/bunny-2-dot-2-0-is-released/).
19
+
20
+ ### More Bunny SSL Options
21
+
22
+ `:mq_tls_ca_certificates` and `:mq_verify_peer` options will now be passed on to Bunny as `:tls_ca_certificates` and `:verify_peer` respectively.
23
+
24
+ Contributed by Kennon Ballou.
25
+
26
+ ## 0.18.0 — August 16th, 2015
2
27
 
3
28
  ### JRuby Support (Using March Hare)
4
29
 
data/README.md CHANGED
@@ -289,6 +289,8 @@ Known configuration parameters are:
289
289
  * `mq_tls`: should TLS be used? (default: `false`)
290
290
  * `mq_tls_cert`: path to client TLS certificate (public key)
291
291
  * `mq_tls_key`: path to client TLS private key
292
+ * `mq_tls_ca_certificates`: array of paths to CA keys (if not specified to Hutch, will default to Bunny defaults which are system-dependent)
293
+ * `mq_verify_peer`: should SSL certificate be verified? (default: `true`)
292
294
  * `require_paths`: array of paths to require
293
295
  * `autoload_rails`: should Hutch command line runner try to automatically load Rails environment files?
294
296
  * `daemonise`: should Hutch runner process daemonise?
@@ -6,10 +6,10 @@ Gem::Specification.new do |gem|
6
6
  gem.add_runtime_dependency 'march_hare', '>= 2.11.0'
7
7
  else
8
8
  gem.platform = Gem::Platform::RUBY
9
- gem.add_runtime_dependency 'bunny', '>= 1.7.0'
9
+ gem.add_runtime_dependency 'bunny', '>= 2.2.0'
10
10
  end
11
11
  gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
12
- gem.add_runtime_dependency 'multi_json', '~> 1.5'
12
+ gem.add_runtime_dependency 'multi_json', '~> 1.11.2'
13
13
  gem.add_runtime_dependency 'activesupport', '>= 3.0'
14
14
  gem.add_development_dependency 'rspec', '~> 3.0'
15
15
  gem.add_development_dependency 'simplecov', '~> 0.7.1'
@@ -3,6 +3,8 @@ require 'hutch/consumer'
3
3
  require 'hutch/worker'
4
4
  require 'hutch/broker'
5
5
  require 'hutch/logging'
6
+ require 'hutch/serializers/identity'
7
+ require 'hutch/serializers/json'
6
8
  require 'hutch/config'
7
9
  require 'hutch/message'
8
10
  require 'hutch/cli'
@@ -195,19 +195,30 @@ module Hutch
195
195
  @channel.nack(delivery_tag, false, false)
196
196
  end
197
197
 
198
- def publish(routing_key, message, properties = {})
198
+ def publish(routing_key, message, properties = {}, options = {})
199
199
  ensure_connection!(routing_key, message)
200
200
 
201
+ serializer = options[:serializer] || @config[:serializer]
202
+
201
203
  non_overridable_properties = {
202
- routing_key: routing_key,
203
- timestamp: @connection.current_timestamp,
204
- content_type: 'application/json'
204
+ routing_key: routing_key,
205
+ timestamp: @connection.current_timestamp,
206
+ content_type: serializer.content_type,
207
+ }
208
+ properties[:message_id] ||= generate_id
209
+
210
+ payload = serializer.encode(message)
211
+ logger.info {
212
+ spec =
213
+ if serializer.binary?
214
+ "#{payload.bytesize} bytes message"
215
+ else
216
+ "message '#{payload}'"
217
+ end
218
+ "publishing #{spec} to #{routing_key}"
205
219
  }
206
- properties[:message_id] ||= generate_id
207
220
 
208
- json = JSON.dump(message)
209
- logger.info("publishing message '#{json}' to #{routing_key}")
210
- response = @exchange.publish(json, {persistent: true}.
221
+ response = @exchange.publish(payload, {persistent: true}.
211
222
  merge(properties).
212
223
  merge(global_properties).
213
224
  merge(non_overridable_properties))
@@ -269,6 +280,10 @@ module Hutch
269
280
  params[:tls] = @config[:mq_tls]
270
281
  params[:tls_key] = @config[:mq_tls_key]
271
282
  params[:tls_cert] = @config[:mq_tls_cert]
283
+ params[:verify_peer] = @config[:mq_verify_peer]
284
+ if @config[:mq_tls_ca_certificates]
285
+ params[:tls_ca_certificates] = @config[:mq_tls_ca_certificates]
286
+ end
272
287
  params[:heartbeat] = @config[:heartbeat]
273
288
  params[:connection_timeout] = @config[:connection_timeout]
274
289
  params[:read_timeout] = @config[:read_timeout]
@@ -354,5 +369,6 @@ module Hutch
354
369
  def global_properties
355
370
  Hutch.global_properties.respond_to?(:call) ? Hutch.global_properties.call : Hutch.global_properties
356
371
  end
372
+
357
373
  end
358
374
  end
@@ -17,6 +17,8 @@ module Hutch
17
17
  mq_tls: false,
18
18
  mq_tls_cert: nil,
19
19
  mq_tls_key: nil,
20
+ mq_tls_ca_certificates: nil,
21
+ mq_verify_peer: true,
20
22
  mq_username: 'guest',
21
23
  mq_password: 'guest',
22
24
  mq_api_host: 'localhost',
@@ -53,6 +55,8 @@ module Hutch
53
55
  client_logger: nil,
54
56
 
55
57
  consumer_pool_size: 1,
58
+
59
+ serializer: Hutch::Serializers::JSON,
56
60
  }.merge(params)
57
61
  end
58
62
 
@@ -19,7 +19,7 @@ module Hutch
19
19
  def requeue!
20
20
  broker.requeue(delivery_info.delivery_tag)
21
21
  end
22
-
22
+
23
23
  def logger
24
24
  Hutch::Logging.logger
25
25
  end
@@ -41,6 +41,11 @@ module Hutch
41
41
  @arguments = arguments
42
42
  end
43
43
 
44
+ # Set custom serializer class, override global value
45
+ def serializer(name)
46
+ @serializer = name
47
+ end
48
+
44
49
  # The RabbitMQ queue name for the consumer. This is derived from the
45
50
  # fully-qualified class name. Module separators are replaced with single
46
51
  # colons, camelcased class names are converted to snake case.
@@ -60,6 +65,10 @@ module Hutch
60
65
  def routing_keys
61
66
  @routing_keys ||= Set.new
62
67
  end
68
+
69
+ def get_serializer
70
+ @serializer
71
+ end
63
72
  end
64
73
  end
65
74
  end
@@ -1,6 +1,4 @@
1
- require 'multi_json'
2
1
  require 'forwardable'
3
- require 'active_support/core_ext/hash/indifferent_access'
4
2
 
5
3
  module Hutch
6
4
  class Message
@@ -8,11 +6,11 @@ module Hutch
8
6
 
9
7
  attr_reader :delivery_info, :properties, :payload
10
8
 
11
- def initialize(delivery_info, properties, payload)
9
+ def initialize(delivery_info, properties, payload, serializer)
12
10
  @delivery_info = delivery_info
13
11
  @properties = properties
14
12
  @payload = payload
15
- @body = MultiJson.load(payload).with_indifferent_access
13
+ @body = serializer.decode(payload)
16
14
  end
17
15
 
18
16
  def_delegator :@body, :[]
@@ -0,0 +1,19 @@
1
+ module Hutch
2
+ module Serializers
3
+ class Identity
4
+
5
+ def self.encode(payload)
6
+ payload
7
+ end
8
+
9
+ def self.decode(payload)
10
+ payload
11
+ end
12
+
13
+ def self.binary? ; false ; end
14
+
15
+ def self.content_type ; nil ; end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require 'multi_json'
2
+ require 'active_support/core_ext/hash/indifferent_access'
3
+
4
+ module Hutch
5
+ module Serializers
6
+ class JSON
7
+
8
+ def self.encode(payload)
9
+ ::JSON.dump(payload)
10
+ end
11
+
12
+ def self.decode(payload)
13
+ ::MultiJson.load(payload).with_indifferent_access
14
+ end
15
+
16
+ def self.binary? ; false ; end
17
+
18
+ def self.content_type ; 'application/json' ; end
19
+
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,4 @@
1
1
  module Hutch
2
- VERSION = '0.18.0'.freeze
2
+ VERSION = '0.19.0'.freeze
3
3
  end
4
4
 
@@ -102,14 +102,18 @@ module Hutch
102
102
  # Called internally when a new messages comes in from RabbitMQ. Responsible
103
103
  # for wrapping up the message and passing it to the consumer.
104
104
  def handle_message(consumer, delivery_info, properties, payload)
105
- logger.info("message(#{properties.message_id || '-'}): " +
106
- "routing key: #{delivery_info.routing_key}, " +
107
- "consumer: #{consumer}, " +
108
- "payload: #{payload}")
109
-
110
105
  broker = @broker
111
106
  begin
112
- message = Message.new(delivery_info, properties, payload)
107
+ serializer = consumer.get_serializer || Hutch::Config[:serializer]
108
+ logger.info {
109
+ spec = serializer.binary? ? "#{payload.bytesize} bytes" : "#{payload}"
110
+ "message(#{properties.message_id || '-'}): " +
111
+ "routing key: #{delivery_info.routing_key}, " +
112
+ "consumer: #{consumer}, " +
113
+ "payload: #{spec}"
114
+ }
115
+
116
+ message = Message.new(delivery_info, properties, payload, serializer)
113
117
  consumer_instance = consumer.new.tap { |c| c.broker, c.delivery_info = @broker, delivery_info }
114
118
  with_tracing(consumer_instance).handle(message)
115
119
  broker.ack(delivery_info.delivery_tag)
@@ -2,10 +2,10 @@ require 'hutch/message'
2
2
 
3
3
  describe Hutch::Message do
4
4
  let(:delivery_info) { double('Delivery Info') }
5
- let(:props) { double('Properties') }
5
+ let(:props) { double('Properties', content_type: "application/json") }
6
6
  let(:body) {{ foo: 'bar' }.with_indifferent_access}
7
7
  let(:json_body) { MultiJson.dump(body) }
8
- subject(:message) { Hutch::Message.new(delivery_info, props, json_body) }
8
+ subject(:message) { Hutch::Message.new(delivery_info, props, json_body, Hutch::Config[:serializer]) }
9
9
 
10
10
  describe '#body' do
11
11
  subject { super().body }
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hutch::Serializers::JSON do
4
+ let(:subject) { described_class }
5
+
6
+ it "encode/decode" do
7
+ payload = { a: 1, b: 2 }
8
+ encoded = subject.encode(payload)
9
+ decoded = subject.decode(encoded)
10
+
11
+ expect(encoded).to eq "{\"a\":1,\"b\":2}"
12
+ expect(decoded).to eq("a" => 1, "b" => 2)
13
+ expect(decoded[:a]).to eq 1
14
+ expect(decoded[:b]).to eq 2
15
+ end
16
+
17
+ end
@@ -3,7 +3,8 @@ require 'hutch/worker'
3
3
 
4
4
  describe Hutch::Worker do
5
5
  let(:consumer) { double('Consumer', routing_keys: %w( a b c ),
6
- get_queue_name: 'consumer', get_arguments: {}) }
6
+ get_queue_name: 'consumer', get_arguments: {},
7
+ get_serializer: nil) }
7
8
  let(:consumers) { [consumer, double('Consumer')] }
8
9
  let(:broker) { Hutch::Broker.new }
9
10
  subject(:worker) { Hutch::Worker.new(broker, consumers) }
@@ -43,7 +44,7 @@ describe Hutch::Worker do
43
44
  let(:consumer_instance) { double('Consumer instance') }
44
45
  let(:delivery_info) { double('Delivery Info', routing_key: '',
45
46
  delivery_tag: 'dt') }
46
- let(:properties) { double('Properties', message_id: nil) }
47
+ let(:properties) { double('Properties', message_id: nil, content_type: "application/json") }
47
48
  before { allow(consumer).to receive_messages(new: consumer_instance) }
48
49
  before { allow(broker).to receive(:ack) }
49
50
  before { allow(broker).to receive(:nack) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hutch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harry Marr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-16 00:00:00.000000000 Z
11
+ date: 2015-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.7.0
19
+ version: 2.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.7.0
26
+ version: 2.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: carrot-top
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.5'
47
+ version: 1.11.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.5'
54
+ version: 1.11.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activesupport
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -132,6 +132,8 @@ files:
132
132
  - lib/hutch/exceptions.rb
133
133
  - lib/hutch/logging.rb
134
134
  - lib/hutch/message.rb
135
+ - lib/hutch/serializers/identity.rb
136
+ - lib/hutch/serializers/json.rb
135
137
  - lib/hutch/tracers.rb
136
138
  - lib/hutch/tracers/newrelic.rb
137
139
  - lib/hutch/tracers/null_tracer.rb
@@ -147,6 +149,7 @@ files:
147
149
  - spec/hutch/error_handlers/sentry_spec.rb
148
150
  - spec/hutch/logger_spec.rb
149
151
  - spec/hutch/message_spec.rb
152
+ - spec/hutch/serializers/json_spec.rb
150
153
  - spec/hutch/worker_spec.rb
151
154
  - spec/hutch_spec.rb
152
155
  - spec/spec_helper.rb
@@ -185,6 +188,7 @@ test_files:
185
188
  - spec/hutch/error_handlers/sentry_spec.rb
186
189
  - spec/hutch/logger_spec.rb
187
190
  - spec/hutch/message_spec.rb
191
+ - spec/hutch/serializers/json_spec.rb
188
192
  - spec/hutch/worker_spec.rb
189
193
  - spec/hutch_spec.rb
190
194
  - spec/spec_helper.rb