honest_pubsub 0.2.4 → 0.3.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: c7c53a089f1fad2b656c8134008f95ce5e4422e7
4
- data.tar.gz: 32c4c3e5f5c90697fdc092d81d2f86e22c126ff1
3
+ metadata.gz: bf7921af321ad1e8d84d9baea70ee538439a7e5f
4
+ data.tar.gz: 6a503f60a553dd038a09baab0918464b551878a0
5
5
  SHA512:
6
- metadata.gz: d4740278b6b995f74e69338bd600ef74e4803a67d1e5584179d73412ce894f889093079eabf594b91900cb0f34737eac393d0a43cef2c1664f0c15c179827220
7
- data.tar.gz: e6f84c3ded8940652bdf7da0a21a9eb159dc633c75e9ae87da27d28cd74037ebb13ee53a5bffe6a84a9a15998af18e982042c151eb5ba1606df205dcde0b409a
6
+ metadata.gz: 4cf1256690f3dd50217c72a7cfa9a00af39fa830cad8ae644c3c079e0a376a2a90fcf1c9354f7480649082ed8591da66fd4e9fb236e58253374161c8adc3a4b1
7
+ data.tar.gz: 9ce9f05eedec207e79e8e0a2354a95374d133ad1c89cd6dca0fdbf32eef455cc3996c390a0e4563e7a6803b4b0dd6624ab1f4a199612681d89e6a7eb25fb8894
data/README.md CHANGED
@@ -56,13 +56,11 @@ Context is automatically cleared up by the gem for a Rails Application. Otherwis
56
56
  You can declare a subscriber class as follows
57
57
 
58
58
  ```ruby
59
- class UserWelcomeSubscriber < HonestPubsub::Server::ClientWorker
59
+ class UserWelcomeSubscriber < HonestPubsub::Subscriber
60
60
  subscribe_to "user_created" # The message prefix that you're subscribing to
61
61
  # subscribe_to "user_created", on: 'welcome_emails_queue' # If you want to specify the queue name
62
62
 
63
- def perform(context, payload)
64
- # context is a hash that was put into HonestPubsub::Context
65
- # Payload contains the data that was published
63
+ def perform(payload)
66
64
  # My awesome logic goes here...
67
65
  end
68
66
  end
@@ -82,6 +80,27 @@ Usage: bundle exec start_subscribers [options]
82
80
 
83
81
  ```
84
82
 
83
+ #### Validations
84
+
85
+ ```ruby
86
+ class UserWelcomeSubscriber < HonestPubsub::Subscriber
87
+ subscribe_to "user_created" # The message prefix that you're subscribing to
88
+ validates_payload_with :id_present
89
+ validates_payload_with do |payload|
90
+ payload[:email].present?
91
+ end
92
+
93
+ def perform(payload)
94
+ # My awesome logic goes here...
95
+ end
96
+
97
+ private
98
+
99
+ def id_present(payload)
100
+ payload[:id].present?
101
+ end
102
+ end
103
+ ```
85
104
 
86
105
  ## Contributing
87
106
 
@@ -10,10 +10,11 @@ require "honest_pubsub/logger"
10
10
  require "honest_pubsub/logging"
11
11
  require "honest_pubsub/message"
12
12
  require "honest_pubsub/publisher"
13
- require "honest_pubsub/subscriber"
13
+ require "honest_pubsub/server/rabbit_mq_subscriber"
14
14
  require "honest_pubsub/version"
15
15
  require "honest_pubsub/exceptions/payload_validation_error"
16
16
  require 'honest_pubsub/server'
17
+ require 'honest_pubsub/subscriber'
17
18
 
18
19
  if defined?(Rails::Railtie)
19
20
  require "honest_pubsub/middleware"
@@ -53,7 +53,7 @@ module HonestPubsub
53
53
  if subscribers.present?
54
54
  subscribers.map(&:constantize)
55
55
  else
56
- HonestPubsub::Server::ClientWorker.class_variable_get(:@@registered_subscribers)
56
+ HonestPubsub::Subscriber.class_variable_get(:@@registered_subscribers)
57
57
  end
58
58
  end
59
59
 
@@ -17,7 +17,7 @@ module HonestPubsub
17
17
  end
18
18
 
19
19
  def start_subscribe
20
- subscriber = ::HonestPubsub::Subscriber.new("")
20
+ subscriber = ::HonestPubsub::Server::RabbitMQSubscriber.new("")
21
21
  subscriber.start("logger") do |info, properties, contents|
22
22
  # Write to mongo the contents and the routing_key, with the routing_key being indexed
23
23
  routing_key = info[:routing_key]
@@ -4,5 +4,4 @@ module HonestPubsub
4
4
  end
5
5
 
6
6
  require 'honest_pubsub/server/client_queue_listener'
7
- require 'honest_pubsub/server/client_worker'
8
7
  require 'honest_pubsub/server/subscriber_server'
@@ -16,7 +16,7 @@ module HonestPubsub
16
16
  @worker_class = worker_class
17
17
  @queue_name = queue
18
18
  @durable = durable
19
- @subscriber = ::HonestPubsub::Subscriber.new(@request_key, @durable, @topic)
19
+ @subscriber = ::HonestPubsub::Server::RabbitMQSubscriber.new(@request_key, @durable, @topic)
20
20
  end
21
21
 
22
22
  def start
@@ -35,8 +35,8 @@ module HonestPubsub
35
35
 
36
36
  def message_received(delivery_info, properties, envelope)
37
37
  HonestPubsub.logger.debug("Message received by listener on #{worker_class.name} with payload: #{envelope[:payload]}")
38
- worker = worker_class.new(delivery_info, properties)
39
- worker.perform!(envelope[:context], envelope[:payload])
38
+ worker = worker_class.new(delivery_info, properties, envelope[:context])
39
+ worker.perform!(envelope[:payload])
40
40
  rescue => e
41
41
  HonestPubsub.logger.error("Failed message for #{worker_class.name}")
42
42
  Airbrake.notify("Failed perform for #{worker_class.name}",
@@ -0,0 +1,72 @@
1
+ module HonestPubsub
2
+ module Server
3
+
4
+ class RabbitMQSubscriber
5
+ attr_reader :listener
6
+ attr_reader :exchange
7
+ attr_reader :channel
8
+
9
+ def initialize(routing_key, durable = true, topic="honest")
10
+ @initial_key = routing_key
11
+ @durable = durable
12
+ @topic = topic
13
+
14
+ if @initial_key.present?
15
+ @routing_key = "#{@topic}.#{@initial_key}.#"
16
+ else
17
+ @routing_key = "#{@topic}.#"
18
+ end
19
+ @logger = ::HonestPubsub::Logger.new
20
+
21
+ self
22
+ end
23
+
24
+ # name - used to ensure that certain consumers are actually listening to an exchange
25
+ # pass in a lambda for this method to work. We might only want to expose the content instead of
26
+ # all 3 chunks.
27
+ def start(name, blocking=false)
28
+ @connection = Bunny.new(Configuration.configuration[:connection])
29
+ begin
30
+ @connection.start
31
+ rescue => e
32
+ Airbrake.notify("RabbitMQ unreachable!", params: { message: e.message}, environment_name: ENV['RAILS_ENV'] )
33
+ raise e
34
+ end
35
+
36
+ @channel = @connection.create_channel
37
+ @exchange = @channel.topic(@topic, :durable=>@durable, :auto_delete=>false)
38
+
39
+ # FIX!!! -thl
40
+ # Need to ensure that the ids for a server will be reproducible in case a server
41
+ # goes down and has to get restarted.
42
+ if @initial_key.present?
43
+ @queue = "#{@initial_key}.#{name}"
44
+ else
45
+ @queue = "#{name}"
46
+ end
47
+
48
+ queue_arguments = {}
49
+ queue_arguments["x-dead-letter-exchange"] = Configuration.configuration[:dead_letter] if Configuration.configuration[:dead_letter].present?
50
+ @listener = @channel.queue(@queue, :arguments=>queue_arguments ).bind(@exchange, :routing_key => @routing_key, :exclusive=>false)
51
+ # Parameters for subscribe that might be useful:
52
+ # :block=>true - Used for long running consumer applications. (backend servers?)
53
+ @consumer = @listener.subscribe(:consumer_tag=>name, :block=>blocking)
54
+ @consumer.on_delivery do |delivery_info, properties, contents|
55
+ HonestPubsub.logger.debug( "Message delivery with contents: #{contents}")
56
+ if delivery_info[:redelivered]
57
+ Airbrake.notify("PubSub Message redelivery", params: {info: delivery_info, props: properties, contents: contents}, environment_name: ENV['RAILS_ENV'] )
58
+ end
59
+ message = ::HonestPubsub::Message.new.parse(contents)
60
+ @logger.log_receive(delivery_info[:routing_key], message)
61
+ yield delivery_info, properties, message
62
+ true
63
+ end
64
+ end
65
+
66
+ def teardown
67
+ @consumer.cancel if @consumer.present?
68
+ @connection.close if @connection.present?
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,69 +1,99 @@
1
+ require 'rubygems'
2
+ require 'active_support/core_ext'
3
+
4
+ # This class provders the worker for executing the subscriber. It receives a message from rabbitmq and
5
+ # creates an instance of the subscriber to execute with the message and context
6
+
1
7
  module HonestPubsub
2
8
  class Subscriber
3
- attr_reader :listener
4
- attr_reader :exchange
5
- attr_reader :channel
6
-
7
- def initialize(routing_key, durable = true, topic="honest")
8
- @initial_key = routing_key
9
- @durable = durable
10
- @topic = topic
11
-
12
- if @initial_key.present?
13
- @routing_key = "#{@topic}.#{@initial_key}.#"
14
- else
15
- @routing_key = "#{@topic}.#"
16
- end
17
- @logger = ::HonestPubsub::Logger.new
9
+ @@registered_subscribers = []
10
+ class_attribute :payload_validators, :error_handlers, :subscribed_key, :subscribed_queue
11
+ attr_accessor :delivery_routing_data, :delivery_properties, :context
18
12
 
19
- self
13
+ def self.inherited(klass)
14
+ @@registered_subscribers << klass
20
15
  end
21
16
 
22
- # name - used to ensure that certain consumers are actually listening to an exchange
23
- # pass in a lambda for this method to work. We might only want to expose the content instead of
24
- # all 3 chunks.
25
- def start(name, blocking=false)
26
- @connection = Bunny.new(Configuration.configuration[:connection])
27
- begin
28
- @connection.start
29
- rescue => e
30
- Airbrake.notify("RabbitMQ unreachable!", params: { message: e.message}, environment_name: ENV['RAILS_ENV'] )
31
- raise e
17
+ # Specify the routing key that the subscriber class should listen to.
18
+ # @param [String] routing_key_name The routing key to subscribe to. Must be characters only separated by periods (.)
19
+ # @param [Hash] options Allowed option is :on to optionally specify a queue. If not provided, queue name is generated from the routing key
20
+ def self.subscribe_to(routing_key_name, options = {})
21
+ options.assert_valid_keys(:on)
22
+ unless validate_routing_key_name(routing_key_name)
23
+ raise ArgumentError.new("#{routing_key_name} is not supported. Only lower case characters separated by periods are allowed.")
32
24
  end
25
+ self.subscribed_key = routing_key_name
26
+ self.subscribed_queue = generated_queue_name(routing_key_name, options[:on])
27
+ end
33
28
 
34
- @channel = @connection.create_channel
35
- @exchange = @channel.topic(@topic, :durable=>@durable, :auto_delete=>false)
29
+ # Sets the validator for payload
30
+ #
31
+ # @param validator The validator to use for validating the payload.
32
+ # Returns false if the payload is not valid.
33
+ # Proc must accept a payload as an argument.
34
+ def self.validates_payload_with(*validators)
35
+ self.payload_validators ||= []
36
+ self.payload_validators += validators
37
+ end
36
38
 
37
- # FIX!!! -thl
38
- # Need to ensure that the ids for a server will be reproducible in case a server
39
- # goes down and has to get restarted.
40
- if @initial_key.present?
41
- @queue = "#{@initial_key}.#{name}"
42
- else
43
- @queue = "#{name}"
44
- end
39
+ # Sets an error handler for the class
40
+ def self.handle_errors_with(handler)
41
+ error_handler = handler
42
+ end
43
+
44
+ # @param [Hash] context Context from invocation
45
+ # @param [Object] delivery_routing_data Contains routing information like originator and routing key
46
+ # @param [Object] delivery_properties
47
+ def initialize(delivery_routing_data, delivery_properties, context)
48
+ @delivery_routing_data = delivery_routing_data
49
+ @delivery_properties = delivery_properties
50
+ @context = context
51
+ end
45
52
 
46
- queue_arguments = {}
47
- queue_arguments["x-dead-letter-exchange"] = Configuration.configuration[:dead_letter] if Configuration.configuration[:dead_letter].present?
48
- @listener = @channel.queue(@queue, :arguments=>queue_arguments ).bind(@exchange, :routing_key => @routing_key, :exclusive=>false)
49
- # Parameters for subscribe that might be useful:
50
- # :block=>true - Used for long running consumer applications. (backend servers?)
51
- @consumer = @listener.subscribe(:consumer_tag=>name, :block=>blocking)
52
- @consumer.on_delivery do |delivery_info, properties, contents|
53
- HonestPubsub.logger.debug( "Message delivery with contents: #{contents}")
54
- if delivery_info[:redelivered]
55
- Airbrake.notify("PubSub Message redelivery", params: {info: delivery_info, props: properties, contents: contents}, environment_name: ENV['RAILS_ENV'] )
56
- end
57
- message = ::HonestPubsub::Message.new.parse(contents)
58
- @logger.log_receive(delivery_info[:routing_key], message)
59
- yield delivery_info, properties, message
60
- true
53
+ # Performs validation if validates_payload_with is defined and then calls the perform method
54
+ # @param [Object] payload Payload of the message
55
+ def perform!(payload)
56
+ if !valid_payload?(payload)
57
+ HonestPubsub.logger.error("Payload validation failed for #{self.class.name}")
58
+ raise ::HonestPubsub::PayloadValidationError.new("Invalid Payload for #{self.class.name}")
61
59
  end
60
+
61
+ perform(context, payload)
62
62
  end
63
63
 
64
- def teardown
65
- @consumer.cancel if @consumer.present?
66
- @connection.close if @connection.present?
64
+ # Actual subscribers need to implement perform method. This is the method where the message is actually processed.
65
+ # @param [Object] payload Payload of the message
66
+ def perform(payload)
67
+ raise "Need implementation for your worker."
67
68
  end
69
+
70
+ # @return [String] The original routing key with which the current message was published
71
+ def routing_key
72
+ delivery_routing_data[:routing_key]
73
+ end
74
+
75
+ # Iterates over all the payload validators and returns false if any of them are false
76
+ # @param [Object] payload The payload/arguments of the message
77
+ # @return [Boolen] Should return true or false value - If no validators are specified, then returns true
78
+ def valid_payload?(payload)
79
+ return true unless payload_validators.present?
80
+
81
+ payload_validators.inject(true) { |is_valid, validator|
82
+ is_valid && (validator.respond_to?(:call) ? validator.call(payload) : send(validator, payload))
83
+ }
84
+ end
85
+
86
+ private
87
+
88
+ def self.validate_routing_key_name(key)
89
+ return true if key.blank?
90
+ key.match(/\A([a-z]+\.?)*([a-z]+)\Z/).present?
91
+ end
92
+
93
+ def self.generated_queue_name(routing_key, queue_name)
94
+ return queue_name if queue_name.present?
95
+ [HonestPubsub::Configuration.application_name.to_s.gsub(/[^\w\_]/, ''), routing_key.gsub(".", '_')].reject(&:blank?).join('_')
96
+ end
97
+
68
98
  end
69
- end
99
+ end
@@ -1,3 +1,3 @@
1
1
  module HonestPubsub
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -123,7 +123,7 @@ describe HonestPubsub::CLI do
123
123
  }
124
124
 
125
125
  context "No subscribers passed through CLI" do
126
- let(:all_subscribers) { HonestPubsub::Server::ClientWorker.class_variable_get(:@@registered_subscribers) }
126
+ let(:all_subscribers) { HonestPubsub::Subscriber.class_variable_get(:@@registered_subscribers) }
127
127
  it "loads all subscribers" do
128
128
  expect(all_subscribers).to include(MyTestSubscriber1)
129
129
  expect(all_subscribers).to include(MyTestSubscriber2)
@@ -13,7 +13,7 @@ describe HonestPubsub::Server::ClientQueueListener do
13
13
 
14
14
  before do
15
15
  context_before
16
- Object.const_set :Klass, Class.new(HonestPubsub::Server::ClientWorker)
16
+ Object.const_set :Klass, Class.new(HonestPubsub::Subscriber)
17
17
  validators.each do |validator|
18
18
  Klass.validates_payload_with validator
19
19
  end
@@ -30,7 +30,7 @@ describe HonestPubsub::Server::ClientQueueListener do
30
30
 
31
31
  context "Normal execution" do
32
32
  let!(:klass_instance){
33
- instance = Klass.new({},{})
33
+ instance = Klass.new({},{}, {})
34
34
  allow(instance).to receive(:perform)
35
35
  instance
36
36
  }
@@ -48,7 +48,7 @@ describe HonestPubsub::Server::ClientQueueListener do
48
48
 
49
49
  context "Exception during execution" do
50
50
  let!(:klass_instance) {
51
- instance = Klass.new({},{})
51
+ instance = Klass.new({},{}, {})
52
52
  allow(instance).to receive(:perform){
53
53
  raise StandardError.new("test")
54
54
  }
@@ -61,7 +61,7 @@ describe HonestPubsub::Server::ClientQueueListener do
61
61
 
62
62
  context "Payload error" do
63
63
  let!(:klass_instance) {
64
- instance = Klass.new({},{})
64
+ instance = Klass.new({},{}, {})
65
65
  allow(instance).to receive(:perform)
66
66
  instance
67
67
  }
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe HonestPubsub::Server::ClientWorker do
4
- before(:each) { Object.const_set :Klass, Class.new(HonestPubsub::Server::ClientWorker) }
3
+ describe HonestPubsub::Subscriber do
4
+ before(:each) { Object.const_set :Klass, Class.new(HonestPubsub::Subscriber) }
5
5
  after(:each) { Object.send :remove_const, :Klass }
6
6
 
7
7
  describe "#routing_key" do
8
- subject { HonestPubsub::Server::ClientWorker.new(routing_data, properties).routing_key }
8
+ subject { HonestPubsub::Subscriber.new(routing_data, properties, {}).routing_key }
9
9
 
10
10
  let(:properties) { {} }
11
11
 
@@ -26,18 +26,18 @@ describe HonestPubsub::Server::ClientWorker do
26
26
  context "One validator" do
27
27
  let(:validators){ [lambda{|payload| true}] }
28
28
  it {
29
- expect(Klass.new({},{}).payload_validators.length).to eq 1 }
29
+ expect(Klass.new({},{}, {}).payload_validators.length).to eq 1 }
30
30
  end
31
31
 
32
32
  context "Two validators" do
33
33
  let(:validators){ [lambda{|payload| true}, lambda{|payload| true}] }
34
- it { expect(Klass.new({},{}).payload_validators.length).to eq 2 }
34
+ it { expect(Klass.new({},{}, {}).payload_validators.length).to eq 2 }
35
35
  end
36
36
  end
37
37
 
38
38
  describe '#valid_payload?' do
39
39
  context
40
- subject { Klass.new({},{}).valid_payload?({}) }
40
+ subject { Klass.new({},{}, {}).valid_payload?({}) }
41
41
 
42
42
  before do
43
43
  validators.each do |validator|
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe HonestPubsub::Server::RabbitMQSubscriber do
4
+ subject { HonestPubsub::Server::RabbitMQSubscriber.new( routing_key ) }
5
+ end
@@ -29,14 +29,14 @@ end
29
29
  HonestPubsub::Configuration.configure_with("test", File.join(HonestPubsub.root,"spec/config.yml") )
30
30
 
31
31
  # Some test subscriber classes to make testing easier
32
- class MyTestSubscriber1 < HonestPubsub::Server::ClientWorker
32
+ class MyTestSubscriber1 < HonestPubsub::Subscriber
33
33
 
34
34
  def perform(payload)
35
35
 
36
36
  end
37
37
  end
38
38
 
39
- class MyTestSubscriber2 < HonestPubsub::Server::ClientWorker
39
+ class MyTestSubscriber2 < HonestPubsub::Subscriber
40
40
  def perform(payload)
41
41
 
42
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honest_pubsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tech@honest.com
@@ -213,16 +213,15 @@ files:
213
213
  - lib/honest_pubsub/railtie.rb
214
214
  - lib/honest_pubsub/server.rb
215
215
  - lib/honest_pubsub/server/client_queue_listener.rb
216
- - lib/honest_pubsub/server/client_worker.rb
216
+ - lib/honest_pubsub/server/rabbit_mq_subscriber.rb
217
217
  - lib/honest_pubsub/server/subscriber_server.rb
218
218
  - lib/honest_pubsub/subscriber.rb
219
219
  - lib/honest_pubsub/version.rb
220
220
  - spec/config.yml
221
- - spec/honest_pubsub/#subscriber_spec.rb#
222
221
  - spec/honest_pubsub/cli_spec.rb
223
222
  - spec/honest_pubsub/server/client_queue_listener_spec.rb
224
223
  - spec/honest_pubsub/server/client_worker_spec.rb
225
- - spec/honest_pubsub/subscriber_spec.rb
224
+ - spec/honest_pubsub/server/rabbitmq_subscriber_spec.rb
226
225
  - spec/logger_spec.rb
227
226
  - spec/message_spec.rb
228
227
  - spec/spec_helper.rb
@@ -252,11 +251,10 @@ specification_version: 4
252
251
  summary: Pub sub gem for Honest Company
253
252
  test_files:
254
253
  - spec/config.yml
255
- - spec/honest_pubsub/#subscriber_spec.rb#
256
254
  - spec/honest_pubsub/cli_spec.rb
257
255
  - spec/honest_pubsub/server/client_queue_listener_spec.rb
258
256
  - spec/honest_pubsub/server/client_worker_spec.rb
259
- - spec/honest_pubsub/subscriber_spec.rb
257
+ - spec/honest_pubsub/server/rabbitmq_subscriber_spec.rb
260
258
  - spec/logger_spec.rb
261
259
  - spec/message_spec.rb
262
260
  - spec/spec_helper.rb
@@ -1,99 +0,0 @@
1
- require 'rubygems'
2
- require 'active_support/core_ext'
3
-
4
- # This class provders the worker for executing the subscriber. It receives a message from rabbitmq and
5
- # creates an instance of the subscriber to execute with the message and context
6
-
7
- module HonestPubsub
8
- module Server
9
- class ClientWorker
10
- @@registered_subscribers = []
11
- class_attribute :payload_validators, :error_handlers, :subscribed_key, :subscribed_queue
12
- attr_accessor :delivery_routing_data, :delivery_properties
13
-
14
- def self.inherited(klass)
15
- @@registered_subscribers << klass
16
- end
17
-
18
- # Specify the routing key that the subscriber class should listen to.
19
- # @param [String] routing_key_name The routing key to subscribe to. Must be characters only separated by periods (.)
20
- # @param [Hash] options Allowed option is :on to optionally specify a queue. If not provided, queue name is generated from the routing key
21
- def self.subscribe_to(routing_key_name, options = {})
22
- options.assert_valid_keys(:on)
23
- unless validate_routing_key_name(routing_key_name)
24
- raise ArgumentError.new("#{routing_key_name} is not supported. Only lower case characters separated by periods are allowed.")
25
- end
26
- self.subscribed_key = routing_key_name
27
- self.subscribed_queue = generated_queue_name(routing_key_name, options[:on])
28
- end
29
-
30
- # Sets the validator for payload
31
- #
32
- # @param validator The validator to use for validating the payload.
33
- # Returns false if the payload is not valid.
34
- # Proc must accept a payload as an argument.
35
- def self.validates_payload_with(*validators)
36
- self.payload_validators ||= []
37
- self.payload_validators += validators
38
- end
39
-
40
- # Sets an error handler for the class
41
- def self.handle_errors_with(handler)
42
- error_handler = handler
43
- end
44
-
45
- def initialize(delivery_routing_data, delivery_properties)
46
- @delivery_routing_data = delivery_routing_data
47
- @delivery_properties = delivery_properties
48
- end
49
-
50
- # Performs validation if validates_payload_with is defined and then calls the perform method
51
- # @param [Object] payload Payload of the message
52
- # @param [Hash] context Context from invocation
53
- def perform!(context, payload)
54
- if !valid_payload?(payload)
55
- HonestPubsub.logger.error("Payload validation failed for #{self.class.name}")
56
- raise ::HonestPubsub::PayloadValidationError.new("Invalid Payload for #{self.class.name}")
57
- end
58
-
59
- perform(context, payload)
60
- end
61
-
62
- # Actual subscribers need to implement perform method. This is the method where the message is actually processed.
63
- # @param [Object] payload Payload of the message
64
- # @param [Hash] context Context from invocation
65
- def perform(context, payload)
66
- raise "Need implementation for your worker."
67
- end
68
-
69
- # @return [String] The original routing key with which the current message was published
70
- def routing_key
71
- delivery_routing_data[:routing_key]
72
- end
73
-
74
- # Iterates over all the payload validators and returns false if any of them are false
75
- # @param [Object] payload The payload/arguments of the message
76
- # @return [Boolen] Should return true or false value - If no validators are specified, then returns true
77
- def valid_payload?(payload)
78
- return true unless payload_validators.present?
79
-
80
- payload_validators.inject(true) { |is_valid, validator|
81
- is_valid && (validator.respond_to?(:call) ? validator.call(payload) : send(validator, payload))
82
- }
83
- end
84
-
85
- private
86
-
87
- def self.validate_routing_key_name(key)
88
- return true if key.blank?
89
- key.match(/\A([a-z]+\.?)*([a-z]+)\Z/).present?
90
- end
91
-
92
- def self.generated_queue_name(routing_key, queue_name)
93
- return queue_name if queue_name.present?
94
- [HonestPubsub::Configuration.application_name.to_s.gsub(/[^\w\_]/, ''), routing_key.gsub(".", '_')].reject(&:blank?).join('_')
95
- end
96
-
97
- end
98
- end
99
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe HonestPubsub::Subscriber do
4
- subject { HonestPubsub::Subscriber.new( routing_key ) }
5
-
6
- describe "#start" do
7
-
8
- end
9
- end
@@ -1,5 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe HonestPubsub::Subscriber do
4
- subject { HonestPubsub::Subscriber.new( routing_key ) }
5
- end