rabbit_feed 2.4.4 → 3.0.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +81 -0
  4. data/README.md +39 -5
  5. data/Rakefile +3 -19
  6. data/bin/rabbit_feed +0 -1
  7. data/example/non_rails_app/Gemfile.lock +29 -32
  8. data/example/non_rails_app/Rakefile +1 -1
  9. data/example/non_rails_app/bin/benchmark +3 -3
  10. data/example/non_rails_app/lib/non_rails_app/event_handler.rb +1 -1
  11. data/example/non_rails_app/spec/lib/non_rails_app/event_handler_spec.rb +3 -4
  12. data/example/non_rails_app/spec/lib/non_rails_app/event_routing_spec.rb +3 -3
  13. data/example/rails_app/Gemfile +4 -16
  14. data/example/rails_app/Gemfile.lock +131 -137
  15. data/example/rails_app/app/assets/javascripts/application.js +0 -1
  16. data/example/rails_app/app/controllers/application_controller.rb +0 -3
  17. data/example/rails_app/app/controllers/beavers_controller.rb +14 -15
  18. data/example/rails_app/bin/rails +1 -1
  19. data/example/rails_app/config/environments/development.rb +1 -1
  20. data/example/rails_app/config/environments/test.rb +2 -2
  21. data/example/rails_app/config/initializers/cookies_serializer.rb +1 -1
  22. data/example/rails_app/config/unicorn.rb +1 -1
  23. data/example/rails_app/config.ru +1 -1
  24. data/example/rails_app/db/schema.rb +5 -7
  25. data/example/rails_app/lib/event_handler.rb +1 -1
  26. data/example/rails_app/spec/controllers/beavers_controller_spec.rb +9 -10
  27. data/example/rails_app/spec/event_routing_spec.rb +1 -2
  28. data/example/rails_app/test/controllers/beavers_controller_test.rb +12 -12
  29. data/lib/dsl.rb +4 -4
  30. data/lib/rabbit_feed/client.rb +17 -23
  31. data/lib/rabbit_feed/configuration.rb +10 -9
  32. data/lib/rabbit_feed/connection.rb +3 -3
  33. data/lib/rabbit_feed/console_consumer.rb +22 -24
  34. data/lib/rabbit_feed/consumer.rb +2 -2
  35. data/lib/rabbit_feed/consumer_connection.rb +21 -22
  36. data/lib/rabbit_feed/event.rb +8 -28
  37. data/lib/rabbit_feed/event_definitions.rb +14 -15
  38. data/lib/rabbit_feed/event_routing.rb +26 -27
  39. data/lib/rabbit_feed/json_log_formatter.rb +1 -1
  40. data/lib/rabbit_feed/producer.rb +13 -13
  41. data/lib/rabbit_feed/producer_connection.rb +8 -9
  42. data/lib/rabbit_feed/testing_support/rspec_matchers/publish_event.rb +52 -89
  43. data/lib/rabbit_feed/testing_support/test_rabbit_feed_consumer.rb +1 -2
  44. data/lib/rabbit_feed/testing_support/testing_helpers.rb +0 -1
  45. data/lib/rabbit_feed/testing_support.rb +5 -6
  46. data/lib/rabbit_feed/version.rb +1 -1
  47. data/lib/rabbit_feed.rb +12 -13
  48. data/rabbit_feed.gemspec +16 -14
  49. data/run_benchmark +4 -3
  50. data/run_example +1 -1
  51. data/spec/features/step_definitions/connectivity_steps.rb +6 -9
  52. data/spec/lib/rabbit_feed/client_spec.rb +8 -9
  53. data/spec/lib/rabbit_feed/configuration_spec.rb +20 -23
  54. data/spec/lib/rabbit_feed/console_consumer_spec.rb +11 -13
  55. data/spec/lib/rabbit_feed/consumer_connection_spec.rb +26 -28
  56. data/spec/lib/rabbit_feed/event_definitions_spec.rb +31 -31
  57. data/spec/lib/rabbit_feed/event_routing_spec.rb +35 -62
  58. data/spec/lib/rabbit_feed/event_spec.rb +40 -87
  59. data/spec/lib/rabbit_feed/producer_connection_spec.rb +11 -7
  60. data/spec/lib/rabbit_feed/producer_spec.rb +16 -19
  61. data/spec/lib/rabbit_feed/testing_support/rspec_matchers/publish_event_spec.rb +82 -87
  62. data/spec/lib/rabbit_feed/testing_support/testing_helper_spec.rb +2 -2
  63. data/spec/spec_helper.rb +4 -10
  64. metadata +67 -45
  65. data/example/rails_app/README.rdoc +0 -28
@@ -10,30 +10,27 @@ module RabbitFeed
10
10
  require_path: '.',
11
11
  config_file: 'config/rabbit_feed.yml',
12
12
  logfile: 'log/rabbit_feed.log',
13
- pidfile: 'tmp/pids/rabbit_feed.pid',
14
- }
13
+ pidfile: 'tmp/pids/rabbit_feed.pid'
14
+ }.freeze
15
15
  DEFAULTS.freeze
16
16
 
17
17
  attr_reader :command, :options
18
18
  validates_presence_of :command, :options
19
- validates :command, inclusion: { in: %w(consume produce shutdown console), message: "%{value} is not a valid command" }
19
+ validates :command, inclusion: { in: %w(consume produce shutdown console), message: '%{value} is not a valid command' }
20
20
  validate :log_file_path_exists
21
21
  validate :config_file_exists
22
22
  validate :require_path_valid, unless: :console?
23
23
  validate :pidfile_path_exists, if: :daemonize?
24
24
  validate :environment_specified
25
25
 
26
- def initialize arguments=ARGV
26
+ def initialize(arguments = ARGV)
27
27
  @command = arguments[0]
28
28
  @options = parse_options arguments
29
-
30
- unless shutdown?
31
- validate!
32
-
33
- set_logging
34
- set_configuration
35
- load_dependancies unless console?
36
- end
29
+ return if shutdown?
30
+ validate!
31
+ set_logging
32
+ set_configuration
33
+ load_dependancies unless console?
37
34
  end
38
35
 
39
36
  def run
@@ -43,25 +40,24 @@ module RabbitFeed
43
40
  private
44
41
 
45
42
  def validate!
46
- raise Error.new errors.messages if invalid?
43
+ raise Error, errors.messages if invalid?
47
44
  end
48
45
 
49
46
  def log_file_path_exists
50
- errors.add(:options, "log file path not found: '#{options[:logfile]}', specify this using the --logfile option") unless Dir.exists?(File.dirname(options[:logfile]))
47
+ errors.add(:options, "log file path not found: '#{options[:logfile]}', specify this using the --logfile option") unless Dir.exist?(File.dirname(options[:logfile]))
51
48
  end
52
49
 
53
50
  def config_file_exists
54
- errors.add(:options, "configuration file not found: '#{options[:config_file]}', specify this using the --config option") unless File.exists?(options[:config_file])
51
+ errors.add(:options, "configuration file not found: '#{options[:config_file]}', specify this using the --config option") unless File.exist?(options[:config_file])
55
52
  end
56
53
 
57
54
  def require_path_valid
58
- if require_rails? && !File.exist?("#{options[:require_path]}/config/application.rb")
59
- errors.add(:options, 'point rabbit_feed to a Rails 3/4 application or a Ruby file to load your worker classes with --require')
60
- end
55
+ return unless require_rails? && !File.exist?("#{options[:require_path]}/config/application.rb")
56
+ errors.add(:options, 'point rabbit_feed to a Rails 3/4 application or a Ruby file to load your worker classes with --require')
61
57
  end
62
58
 
63
59
  def pidfile_path_exists
64
- errors.add(:options, "pid file path not found: '#{options[:pidfile]}', specify this using the --pidfile option") unless Dir.exists?(File.dirname(options[:pidfile]))
60
+ errors.add(:options, "pid file path not found: '#{options[:pidfile]}', specify this using the --pidfile option") unless Dir.exist?(File.dirname(options[:pidfile]))
65
61
  end
66
62
 
67
63
  def environment_specified
@@ -145,11 +141,10 @@ module RabbitFeed
145
141
  File.directory?(options[:require_path])
146
142
  end
147
143
 
148
- def parse_options argv
144
+ def parse_options(argv)
149
145
  opts = {}
150
146
 
151
147
  parser = OptionParser.new do |o|
152
-
153
148
  o.on '-a', '--application VAL', 'Name of the application' do |arg|
154
149
  opts[:application] = arg
155
150
  end
@@ -190,7 +185,7 @@ module RabbitFeed
190
185
  opts[:pidfile] = arg
191
186
  end
192
187
 
193
- o.on '-V', '--version', 'Print version and exit' do |arg|
188
+ o.on '-V', '--version', 'Print version and exit' do |_arg|
194
189
  puts "RabbitFeed #{RabbitFeed::VERSION}"
195
190
  exit 0
196
191
  end
@@ -204,6 +199,5 @@ module RabbitFeed
204
199
  parser.parse! argv
205
200
  DEFAULTS.merge opts
206
201
  end
207
-
208
202
  end
209
203
  end
@@ -7,8 +7,8 @@ module RabbitFeed
7
7
  :consumer_exit_after_fail
8
8
  validates_presence_of :application, :environment, :exchange
9
9
 
10
- def initialize options
11
- RabbitFeed.log.info {{ event: :initialize_configuration, options: options.merge({password: :redacted}) }}
10
+ def initialize(options)
11
+ RabbitFeed.log.info { { event: :initialize_configuration, options: options.merge(password: :redacted) } }
12
12
 
13
13
  @host = options[:host]
14
14
  @hosts = options[:hosts]
@@ -28,10 +28,10 @@ module RabbitFeed
28
28
  validate!
29
29
  end
30
30
 
31
- def self.load file_path, environment, application
32
- RabbitFeed.log.info {{ event: :load_configuration_file, file_path: file_path, environment: environment, application: application }}
31
+ def self.load(file_path, environment, application)
32
+ RabbitFeed.log.info { { event: :load_configuration_file, file_path: file_path, environment: environment, application: application } }
33
33
 
34
- raise ConfigurationError.new "The RabbitFeed configuration file path specified does not exist: #{file_path}" unless (File.exist? file_path)
34
+ raise ConfigurationError, "The RabbitFeed configuration file path specified does not exist: #{file_path}" unless File.exist? file_path
35
35
 
36
36
  options = read_configuration_file file_path, environment
37
37
  options[:environment] = environment
@@ -48,7 +48,7 @@ module RabbitFeed
48
48
  end
49
49
 
50
50
  def connection_options
51
- Hash.new.tap do |options|
51
+ {}.tap do |options|
52
52
  options[:heartbeat] = heartbeat if heartbeat
53
53
  options[:connect_timeout] = connect_timeout if connect_timeout
54
54
  options[:host] = host if host
@@ -65,13 +65,14 @@ module RabbitFeed
65
65
 
66
66
  private
67
67
 
68
- def self.read_configuration_file file_path, environment
68
+ def self.read_configuration_file(file_path, environment)
69
69
  raw_configuration = YAML.load(ERB.new(File.read(file_path)).result)
70
- HashWithIndifferentAccess.new (raw_configuration[environment] || {})
70
+ HashWithIndifferentAccess.new(raw_configuration[environment] || {})
71
71
  end
72
+ private_class_method :read_configuration_file
72
73
 
73
74
  def validate!
74
- raise ConfigurationError.new errors.messages if invalid?
75
+ raise ConfigurationError, errors.messages if invalid?
75
76
  end
76
77
  end
77
78
  end
@@ -3,10 +3,10 @@ module RabbitFeed
3
3
  include Singleton
4
4
 
5
5
  def initialize
6
- RabbitFeed.log.info {{ event: :connecting_to_rabbitmq, options: RabbitFeed.configuration.connection_options.merge({password: :redacted, logger: :redacted}) }}
6
+ RabbitFeed.log.info { { event: :connecting_to_rabbitmq, options: RabbitFeed.configuration.connection_options.merge(password: :redacted, logger: :redacted) } }
7
7
  @connection = Bunny.new RabbitFeed.configuration.connection_options
8
8
  @connection.start
9
- RabbitFeed.log.info {{ event: :connected_to_rabbitmq }}
9
+ RabbitFeed.log.info { { event: :connected_to_rabbitmq } }
10
10
  @channel = @connection.create_channel
11
11
  @mutex = Mutex.new
12
12
  end
@@ -15,7 +15,7 @@ module RabbitFeed
15
15
 
16
16
  attr_reader :channel, :mutex
17
17
 
18
- def synchronized &block
18
+ def synchronized
19
19
  mutex.synchronize do
20
20
  yield
21
21
  end
@@ -2,7 +2,7 @@ module RabbitFeed
2
2
  module ConsoleConsumer
3
3
  extend self
4
4
 
5
- APPLICATION_NAME = 'rabbit_feed_console'
5
+ APPLICATION_NAME = 'rabbit_feed_console'.freeze
6
6
 
7
7
  def init
8
8
  @event_count = 0
@@ -10,10 +10,10 @@ module RabbitFeed
10
10
  route_all_events
11
11
  puts welcome_message
12
12
  ask_to_purge_queue unless queue_empty?
13
- puts "Ready. Press CTRL+C to exit."
13
+ puts 'Ready. Press CTRL+C to exit.'
14
14
  end
15
15
 
16
- def formatted event
16
+ def formatted(event)
17
17
  Formatter.new(event).to_s
18
18
  end
19
19
 
@@ -28,10 +28,9 @@ module RabbitFeed
28
28
  private
29
29
 
30
30
  def welcome_message
31
- """RabbitFeed console starting at #{Time.now.utc}...
32
- Environment: #{RabbitFeed.environment}
33
- Queue: #{RabbitFeed.configuration.queue}
34
- """
31
+ "RabbitFeed console starting at #{Time.now.utc}...\n"\
32
+ "Environment: #{RabbitFeed.environment}\n"\
33
+ "Queue: #{RabbitFeed.configuration.queue}"
35
34
  end
36
35
 
37
36
  def queue_empty?
@@ -39,15 +38,15 @@ Queue: #{RabbitFeed.configuration.queue}
39
38
  end
40
39
 
41
40
  def ask_to_purge_queue
42
- puts "There are currently #{ConsumerConnection.instance.queue_depth} message(s) in the console's queue.\n"+
43
- "Would you like to purge the queue before proceeding? (y/N)>"
41
+ puts "There are currently #{ConsumerConnection.instance.queue_depth} message(s) in the console's queue.\n"\
42
+ 'Would you like to purge the queue before proceeding? (y/N)>'
44
43
  response = STDIN.gets.chomp
45
44
  purge_queue if response == 'y'
46
45
  end
47
46
 
48
47
  def purge_queue
49
48
  ConsumerConnection.instance.purge_queue
50
- puts "Queue purged."
49
+ puts 'Queue purged.'
51
50
  end
52
51
 
53
52
  def route_all_events
@@ -56,7 +55,7 @@ Queue: #{RabbitFeed.configuration.queue}
56
55
  accept_from(:any) do
57
56
  event(:any) do |event|
58
57
  scope.increment_event_count
59
- puts (scope.formatted event)
58
+ puts scope.formatted(event)
60
59
  puts scope.event_count_message
61
60
  end
62
61
  end
@@ -68,15 +67,14 @@ Queue: #{RabbitFeed.configuration.queue}
68
67
  end
69
68
 
70
69
  class Formatter
71
-
72
70
  BORDER_WIDTH = 100
73
- BORDER_CHAR = "-"
74
- DIVIDER_CHAR = "*"
75
- NEWLINE = "\n"
71
+ BORDER_CHAR = '-'.freeze
72
+ DIVIDER_CHAR = '*'.freeze
73
+ NEWLINE = "\n".freeze
76
74
 
77
75
  attr_reader :event
78
76
 
79
- def initialize event
77
+ def initialize(event)
80
78
  @event = event
81
79
  end
82
80
 
@@ -88,12 +86,12 @@ Queue: #{RabbitFeed.configuration.queue}
88
86
 
89
87
  def header
90
88
  event_detail = "#{event.name}: #{event.created_at_utc}"
91
- border_filler = BORDER_CHAR*((BORDER_WIDTH - event_detail.length)/2)
92
- border_filler+event_detail+border_filler
89
+ border_filler = BORDER_CHAR * ((BORDER_WIDTH - event_detail.length) / 2)
90
+ border_filler + event_detail + border_filler
93
91
  end
94
92
 
95
93
  def footer
96
- BORDER_CHAR*BORDER_WIDTH
94
+ BORDER_CHAR * BORDER_WIDTH
97
95
  end
98
96
 
99
97
  def metadata
@@ -101,18 +99,18 @@ Queue: #{RabbitFeed.configuration.queue}
101
99
  end
102
100
 
103
101
  def divider
104
- DIVIDER_CHAR*BORDER_WIDTH
102
+ DIVIDER_CHAR * BORDER_WIDTH
105
103
  end
106
104
 
107
105
  def payload
108
106
  pretty_print_hash 'Event payload', event.payload
109
107
  end
110
108
 
111
- def pretty_print_hash description, hash
109
+ def pretty_print_hash(description, hash)
112
110
  '#' + description + NEWLINE +
113
- hash.keys.sort.map do |key|
114
- "#{key}: #{hash[key]}"
115
- end.join(NEWLINE)
111
+ hash.keys.sort.map do |key|
112
+ "#{key}: #{hash[key]}"
113
+ end.join(NEWLINE)
116
114
  end
117
115
  end
118
116
  end
@@ -7,9 +7,9 @@ module RabbitFeed
7
7
  def run
8
8
  ConsumerConnection.instance.consume do |raw_event|
9
9
  event = Event.deserialize raw_event
10
- RabbitFeed.log.info {{ event: :message_received, metadata: event.metadata }}
10
+ RabbitFeed.log.info { { event: :message_received, metadata: event.metadata } }
11
11
  event_routing.handle_event event
12
- RabbitFeed.log.info {{ event: :message_processed, metadata: event.metadata }}
12
+ RabbitFeed.log.info { { event: :message_processed, metadata: event.metadata } }
13
13
  end
14
14
  end
15
15
  end
@@ -1,6 +1,5 @@
1
1
  module RabbitFeed
2
2
  class ConsumerConnection < RabbitFeed::Connection
3
-
4
3
  SUBSCRIPTION_OPTIONS = {
5
4
  consumer_tag: Socket.gethostname, # Use the host name of the server
6
5
  manual_ack: true, # Manually acknowledge messages once they've been processed
@@ -15,30 +14,30 @@ module RabbitFeed
15
14
  arguments: {
16
15
  'x-ha-policy' => 'all', # Apply the queue on all mirrors
17
16
  'x-expires' => SEVEN_DAYS_IN_MS, # Auto-delete the queue after a period of inactivity (in ms)
18
- },
17
+ }
19
18
  }.freeze
20
19
 
21
20
  def initialize
22
21
  super
23
22
  channel.prefetch(1)
24
23
  @queue = channel.queue RabbitFeed.configuration.queue, queue_options
25
- RabbitFeed.log.info {{ event: :queue_declared, queue: RabbitFeed.configuration.queue, options: queue_options }}
24
+ RabbitFeed.log.info { { event: :queue_declared, queue: RabbitFeed.configuration.queue, options: queue_options } }
26
25
  bind_on_accepted_routes
27
26
  end
28
27
 
29
- def consume &block
28
+ def consume(&block)
30
29
  raise 'This connection already has a consumer subscribed' if connection_in_use?
31
30
  synchronized do
32
31
  begin
33
- RabbitFeed.log.info {{ event: :subscribe_to_queue, queue: RabbitFeed.configuration.queue }}
32
+ RabbitFeed.log.info { { event: :subscribe_to_queue, queue: RabbitFeed.configuration.queue } }
34
33
 
35
- consumer = queue.subscribe(SUBSCRIPTION_OPTIONS) do |delivery_info, properties, payload|
34
+ consumer = queue.subscribe(SUBSCRIPTION_OPTIONS) do |delivery_info, _properties, payload|
36
35
  handle_message delivery_info, payload, &block
37
36
  end
38
37
 
39
38
  sleep # Sleep indefinitely, as the consumer runs in its own thread
40
- rescue SystemExit, Interrupt, SignalException
41
- RabbitFeed.log.info {{ event: :unsubscribe_from_queue, queue: RabbitFeed.configuration.queue }}
39
+ rescue SystemExit, SignalException
40
+ RabbitFeed.log.info { { event: :unsubscribe_from_queue, queue: RabbitFeed.configuration.queue } }
42
41
  ensure
43
42
  (cancel_consumer consumer) if consumer.present?
44
43
  end
@@ -59,29 +58,29 @@ module RabbitFeed
59
58
 
60
59
  def queue_options
61
60
  {
62
- auto_delete: RabbitFeed.configuration.auto_delete_queue,
61
+ auto_delete: RabbitFeed.configuration.auto_delete_queue
63
62
  }.merge QUEUE_OPTIONS
64
63
  end
65
64
 
66
65
  def bind_on_accepted_routes
67
66
  if RabbitFeed::Consumer.event_routing.present?
68
67
  RabbitFeed::Consumer.event_routing.accepted_routes.each do |accepted_route|
69
- queue.bind(RabbitFeed.configuration.exchange, { routing_key: accepted_route })
70
- RabbitFeed.log.info {{ event: :queue_bound, queue: RabbitFeed.configuration.queue, exchange: RabbitFeed.configuration.exchange, routing_key: accepted_route }}
68
+ queue.bind(RabbitFeed.configuration.exchange, routing_key: accepted_route)
69
+ RabbitFeed.log.info { { event: :queue_bound, queue: RabbitFeed.configuration.queue, exchange: RabbitFeed.configuration.exchange, routing_key: accepted_route } }
71
70
  end
72
71
  else
73
72
  queue.bind(RabbitFeed.configuration.exchange)
74
- RabbitFeed.log.info {{ event: :queue_bound, queue: RabbitFeed.configuration.queue, exchange: RabbitFeed.configuration.exchange }}
73
+ RabbitFeed.log.info { { event: :queue_bound, queue: RabbitFeed.configuration.queue, exchange: RabbitFeed.configuration.exchange } }
75
74
  end
76
75
  end
77
76
 
78
- def acknowledge delivery_info
77
+ def acknowledge(delivery_info)
79
78
  queue.channel.ack(delivery_info.delivery_tag)
80
- RabbitFeed.log.debug {{ event: :acknowledge, delivery_tag: delivery_info.delivery_tag }}
79
+ RabbitFeed.log.debug { { event: :acknowledge, delivery_tag: delivery_info.delivery_tag } }
81
80
  end
82
81
 
83
- def handle_message delivery_info, payload, &block
84
- RabbitFeed.log.debug {{ event: :handling_message, delivery_tag: delivery_info.delivery_tag }}
82
+ def handle_message(delivery_info, payload)
83
+ RabbitFeed.log.debug { { event: :handling_message, delivery_tag: delivery_info.delivery_tag } }
85
84
  begin
86
85
  yield payload
87
86
  acknowledge delivery_info
@@ -91,21 +90,21 @@ module RabbitFeed
91
90
  end
92
91
  end
93
92
 
94
- def cancel_consumer consumer
93
+ def cancel_consumer(consumer)
95
94
  cancel_ok = consumer.cancel
96
- RabbitFeed.log.debug {{ event: :consumer_cancelled, status: cancel_ok, queue: RabbitFeed.configuration.queue }}
95
+ RabbitFeed.log.debug { { event: :consumer_cancelled, status: cancel_ok, queue: RabbitFeed.configuration.queue } }
97
96
  end
98
97
 
99
- def negative_acknowledge delivery_info
98
+ def negative_acknowledge(delivery_info)
100
99
  # Tell rabbit that we were unable to process the message
101
100
  # This will re-queue the message
102
101
  queue.channel.nack(delivery_info.delivery_tag, false, true)
103
- RabbitFeed.log.debug {{ event: :negative_acknowledge, delivery_tag: delivery_info.delivery_tag }}
102
+ RabbitFeed.log.debug { { event: :negative_acknowledge, delivery_tag: delivery_info.delivery_tag } }
104
103
  end
105
104
 
106
- def handle_processing_exception delivery_info, exception
105
+ def handle_processing_exception(delivery_info, exception)
107
106
  negative_acknowledge delivery_info
108
- RabbitFeed.log.error {{ event: :processing_exception, delivery_tag: delivery_info.delivery_tag, message: exception.message, backtrace: exception.backtrace.join(',') }}
107
+ RabbitFeed.log.error { { event: :processing_exception, delivery_tag: delivery_info.delivery_tag, message: exception.message, backtrace: exception.backtrace.join(',') } }
109
108
  RabbitFeed.exception_notify exception
110
109
  end
111
110
  end
@@ -2,14 +2,14 @@ module RabbitFeed
2
2
  class Event
3
3
  include ActiveModel::Validations
4
4
 
5
- SCHEMA_VERSION = '2.0.0'
5
+ SCHEMA_VERSION = '2.0.0'.freeze
6
6
 
7
7
  attr_reader :schema, :payload, :metadata, :sensitive_fields
8
8
  validates :metadata, presence: true
9
9
  validates :payload, length: { minimum: 0, allow_nil: false, message: 'can\'t be nil' }
10
10
  validate :required_metadata
11
11
 
12
- def initialize metadata, payload={}, schema=nil, sensitive_fields=[]
12
+ def initialize(metadata, payload = {}, schema = nil, sensitive_fields = [])
13
13
  @schema = schema
14
14
  @payload = payload.with_indifferent_access if payload
15
15
  @metadata = metadata.with_indifferent_access if metadata
@@ -40,8 +40,7 @@ module RabbitFeed
40
40
  end
41
41
 
42
42
  class << self
43
-
44
- def deserialize serialized_event
43
+ def deserialize(serialized_event)
45
44
  datum_reader = Avro::IO::DatumReader.new
46
45
  reader = Avro::DataFile::Reader.new (StringIO.new serialized_event), datum_reader
47
46
  event_hash = nil
@@ -49,25 +48,7 @@ module RabbitFeed
49
48
  event_hash = datum
50
49
  end
51
50
  reader.close
52
- if (version_1? event_hash)
53
- new_from_version_1 event_hash, datum_reader.readers_schema
54
- else
55
- new event_hash['metadata'], event_hash['payload'], datum_reader.readers_schema
56
- end
57
- end
58
-
59
- private
60
-
61
- def version_1? event_hash
62
- %w(metadata payload).none?{|key| event_hash.has_key? key}
63
- end
64
-
65
- def new_from_version_1 metadata_and_payload, schema
66
- metadata = {}
67
- %w(application name host version environment created_at_utc).each do |field|
68
- metadata[field] = metadata_and_payload.delete field
69
- end
70
- new metadata, metadata_and_payload, schema
51
+ new event_hash['metadata'], event_hash['payload'], datum_reader.readers_schema
71
52
  end
72
53
  end
73
54
 
@@ -75,18 +56,17 @@ module RabbitFeed
75
56
 
76
57
  def sensitive_proof_payload
77
58
  sensitive_fields.each_with_object(payload.dup) do |field, clean_payload|
78
- clean_payload[field] = "[REMOVED]" if clean_payload.key?(field)
59
+ clean_payload[field] = '[REMOVED]' if clean_payload.key?(field)
79
60
  end
80
61
  end
81
62
 
82
63
  def validate!
83
- raise Error.new "Invalid event: #{errors.messages}" if invalid?
64
+ raise Error, "Invalid event: #{errors.messages}" if invalid?
84
65
  end
85
66
 
86
67
  def required_metadata
87
- if metadata
88
- errors.add(:metadata, 'name field is required') if metadata[:name].blank?
89
- end
68
+ return unless metadata
69
+ errors.add(:metadata, 'name field is required') if metadata[:name].blank?
90
70
  end
91
71
  end
92
72
  end
@@ -1,13 +1,12 @@
1
1
  module RabbitFeed
2
2
  class EventDefinitions
3
-
4
3
  class Field
5
4
  include ActiveModel::Validations
6
5
 
7
6
  attr_reader :name, :type, :definition
8
7
  validates_presence_of :name, :type, :definition
9
8
 
10
- def initialize name, type, definition
9
+ def initialize(name, type, definition)
11
10
  @name = name
12
11
  @type = type
13
12
  @definition = definition
@@ -21,7 +20,7 @@ module RabbitFeed
21
20
  private
22
21
 
23
22
  def validate!
24
- raise ConfigurationError.new "Bad field specification for #{name}: #{errors.messages}" if invalid?
23
+ raise ConfigurationError, "Bad field specification for #{name}: #{errors.messages}" if invalid?
25
24
  end
26
25
  end
27
26
 
@@ -33,24 +32,24 @@ module RabbitFeed
33
32
  validate :schema_parseable
34
33
  validates :version, format: { with: /\A\d+\.\d+\.\d+\z/, message: 'must be in *.*.* format' }
35
34
 
36
- def initialize name, version
35
+ def initialize(name, version)
37
36
  @name = name
38
37
  @version = version
39
38
  @fields = []
40
39
  @sensitive_fields = []
41
40
  end
42
41
 
43
- def payload_contains &block
44
- self.instance_eval(&block)
42
+ def payload_contains(&block)
43
+ instance_eval(&block)
45
44
  end
46
45
 
47
- def field name, options
46
+ def field(name, options)
48
47
  sensitive_fields << name.to_s if options.delete(:sensitive)
49
48
  fields << (Field.new name, options[:type], options[:definition])
50
49
  end
51
50
 
52
- def defined_as &block
53
- @definition = block.call if block.present?
51
+ def defined_as(&block)
52
+ @definition = yield if block.present?
54
53
  end
55
54
 
56
55
  def payload_schema
@@ -65,23 +64,23 @@ module RabbitFeed
65
64
  (Field.new 'version', 'string', 'The version of the event payload'),
66
65
  (Field.new 'schema_version', 'string', 'The version of the event schema'),
67
66
  (Field.new 'name', 'string', 'The name of the event'),
68
- (Field.new 'created_at_utc', 'string', 'The UTC time that the event was created'),
67
+ (Field.new 'created_at_utc', 'string', 'The UTC time that the event was created')
69
68
  ].map(&:schema) }
70
69
  end
71
70
 
72
71
  def event_schema
73
72
  [
74
73
  { name: 'payload', type: payload_schema, doc: 'The event payload (defined by the source system)' },
75
- { name: 'metadata', type: metadata_schema, doc: 'The event metadata (defined by rabbit feed)' },
74
+ { name: 'metadata', type: metadata_schema, doc: 'The event metadata (defined by rabbit feed)' }
76
75
  ]
77
76
  end
78
77
 
79
78
  def schema
80
- @schema ||= (Avro::Schema.parse ({ name: name, type: 'record', doc: definition, fields: event_schema }.to_json))
79
+ @schema ||= Avro::Schema.parse({ name: name, type: 'record', doc: definition, fields: event_schema }.to_json)
81
80
  end
82
81
 
83
82
  def validate!
84
- raise ConfigurationError.new "Bad event specification for #{name}: #{errors.messages}" if invalid?
83
+ raise ConfigurationError, "Bad event specification for #{name}: #{errors.messages}" if invalid?
85
84
  end
86
85
 
87
86
  private
@@ -99,13 +98,13 @@ module RabbitFeed
99
98
  @events = {}
100
99
  end
101
100
 
102
- def define_event name, options, &block
101
+ def define_event(name, options, &block)
103
102
  events[name] = Event.new name, options[:version]
104
103
  events[name].instance_eval(&block)
105
104
  events[name].validate!
106
105
  end
107
106
 
108
- def [] name
107
+ def [](name)
109
108
  events[name]
110
109
  end
111
110
  end