eventhub-processor2 1.5.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,20 +7,19 @@ module EventHub
7
7
  finalizer :cleanup
8
8
 
9
9
  def initialize
10
- EventHub.logger.info('Watchdog is starting...')
10
+ EventHub.logger.info("Watchdog is starting...")
11
11
  async.start
12
12
  end
13
13
 
14
14
  def start
15
15
  loop do
16
- EventHub.logger.info('Running watchdog...')
17
16
  watch
18
17
  sleep Configuration.processor[:watchdog_cycle_in_s]
19
18
  end
20
19
  end
21
20
 
22
21
  def cleanup
23
- EventHub.logger.info('Watchdog is cleaning up...')
22
+ EventHub.logger.info("Watchdog is cleaning up...")
24
23
  end
25
24
 
26
25
  private
@@ -36,7 +35,7 @@ module EventHub
36
35
  end
37
36
  end
38
37
  ensure
39
- connection.close if connection
38
+ connection&.close
40
39
  end
41
40
  end
42
41
  end
data/lib/eventhub/base.rb CHANGED
@@ -1,36 +1,29 @@
1
- require 'uuidtools'
2
- require 'json'
3
- require 'base64'
4
- require 'optparse'
1
+ require "uuidtools"
2
+ require "json"
3
+ require "base64"
4
+ require "optparse"
5
5
 
6
- require 'eventhub/components'
7
- require 'logstash-logger'
8
- require 'bunny'
6
+ require "eventhub/components"
7
+ require "logstash-logger"
8
+ require "bunny"
9
+ require "celluloid"
9
10
 
10
- # Maybe needs refactoring in future versions ?!
11
- if ENV['RSPEC_PROCESSOR2']
12
- require 'celluloid'
13
- else
14
- # celluloid is booting automatically
15
- require 'celluloid/current'
16
- end
17
-
18
- require_relative 'version'
19
- require_relative 'constant'
20
- require_relative 'base_exception'
21
- require_relative 'logger'
22
- require_relative 'helper'
23
- require_relative 'sleeper'
24
- require_relative 'hash_extensions'
25
- require_relative 'configuration'
26
- require_relative 'message'
27
- require_relative 'statistics'
28
- require_relative 'consumer'
29
- require_relative 'actor_heartbeat'
30
- require_relative 'actor_watchdog'
31
- require_relative 'actor_publisher'
32
- require_relative 'actor_listener'
33
- require_relative 'processor2'
11
+ require_relative "version"
12
+ require_relative "constant"
13
+ require_relative "base_exception"
14
+ require_relative "logger"
15
+ require_relative "helper"
16
+ require_relative "sleeper"
17
+ require_relative "hash_extensions"
18
+ require_relative "configuration"
19
+ require_relative "message"
20
+ require_relative "statistics"
21
+ require_relative "consumer"
22
+ require_relative "actor_heartbeat"
23
+ require_relative "actor_watchdog"
24
+ require_relative "actor_publisher"
25
+ require_relative "actor_listener"
26
+ require_relative "processor2"
34
27
 
35
28
  Celluloid.logger = nil
36
29
  Celluloid.exception_handler { |ex| EventHub.logger.error "Exception occured: #{ex}" }
@@ -3,9 +3,9 @@ module EventHub
3
3
  # BaseException class
4
4
  class BaseException < RuntimeError
5
5
  attr_accessor :code, :message
6
- def initialize(message=nil, code=EventHub::STATUS_DEADLETTER)
6
+ def initialize(message = nil, code = EventHub::STATUS_DEADLETTER)
7
7
  @message = message
8
- @code = code
8
+ @code = code
9
9
  super(@message)
10
10
  end
11
11
  end
@@ -6,16 +6,16 @@ module EventHub
6
6
  extend self
7
7
  extend Helper
8
8
 
9
- attr_reader :name # name of processor
10
- attr_reader :environment # environment the processor is running
11
- attr_reader :detached # run processor run as a daemon
12
- attr_reader :config_file # name of configuration file
13
- attr_reader :config_data # data from configuration file
14
-
15
- @name = 'undefined'
16
- @environment = 'development'
9
+ attr_reader :name # name of processor
10
+ attr_reader :environment # environment the processor is running
11
+ attr_reader :detached # run processor run as a daemon
12
+ attr_reader :config_file # name of configuration file
13
+ attr_reader :config_data # data from configuration file
14
+
15
+ @name = "undefined"
16
+ @environment = "development"
17
17
  @detached = false
18
- @config_file = File.join(Dir.getwd, 'config', "#{@name}.json")
18
+ @config_file = File.join(Dir.getwd, "config", "#{@name}.json")
19
19
  @config_data = {}
20
20
 
21
21
  # set name of processor
@@ -24,32 +24,32 @@ module EventHub
24
24
  end
25
25
 
26
26
  def reset
27
- @name = 'undefined'
28
- @environment = 'development'
27
+ @name = "undefined"
28
+ @environment = "development"
29
29
  @detached = false
30
- @config_file = File.join(Dir.getwd, 'config', "#{@name}.json")
30
+ @config_file = File.join(Dir.getwd, "config", "#{@name}.json")
31
31
  @config_data = {}
32
32
  end
33
33
 
34
34
  # parse options from argument list
35
35
  def parse_options(argv = ARGV)
36
- @config_file = File.join(Dir.getwd, 'config', "#{@name}.json")
36
+ @config_file = File.join(Dir.getwd, "config", "#{@name}.json")
37
37
 
38
- OptionParser.new do |opts|
39
- note = 'Define environment'
40
- opts.on('-e', '--environment ENVIRONMENT', note) do |environment|
38
+ OptionParser.new { |opts|
39
+ note = "Define environment"
40
+ opts.on("-e", "--environment ENVIRONMENT", note) do |environment|
41
41
  @environment = environment
42
42
  end
43
43
 
44
- opts.on('-d', '--detached', 'Run processor detached as a daemon') do
44
+ opts.on("-d", "--detached", "Run processor detached as a daemon") do
45
45
  @detached = true
46
46
  end
47
47
 
48
- note = 'Define configuration file'
49
- opts.on('-c', '--config CONFIG', note) do |config|
48
+ note = "Define configuration file"
49
+ opts.on("-c", "--config CONFIG", note) do |config|
50
50
  @config_file = config
51
51
  end
52
- end.parse!(argv)
52
+ }.parse!(argv)
53
53
 
54
54
  true
55
55
  rescue OptionParser::InvalidOption => e
@@ -71,7 +71,7 @@ module EventHub
71
71
  new_data = JSON.parse(File.read(@config_file), symbolize_names: true)
72
72
  rescue => e
73
73
  EventHub.logger.warn("Exception while loading configuration file: #{e}")
74
- EventHub.logger.info('Using default configuration values')
74
+ EventHub.logger.info("Using default configuration values")
75
75
  end
76
76
 
77
77
  deep_merge!(@config_data, default_configuration)
@@ -94,13 +94,18 @@ module EventHub
94
94
  fail(NoMethodError, "unknown configuration [#{name}]", caller)
95
95
  end
96
96
 
97
+ def respond_to_missing?(name, include_private = false)
98
+ return true if @config_data[name.to_sym]
99
+ false
100
+ end
101
+
97
102
  def default_configuration
98
103
  {
99
104
  server: {
100
- user: 'guest',
101
- password: 'guest',
102
- host: 'localhost',
103
- vhost: 'event_hub',
105
+ user: "guest",
106
+ password: "guest",
107
+ host: "localhost",
108
+ vhost: "event_hub",
104
109
  port: 5672,
105
110
  tls: false,
106
111
  tls_cert: nil,
@@ -111,7 +116,7 @@ module EventHub
111
116
  },
112
117
  processor: {
113
118
  heartbeat_cycle_in_s: 300,
114
- watchdog_cycle_in_s: 15,
119
+ watchdog_cycle_in_s: 60,
115
120
  restart_in_s: 15,
116
121
  listener_queues: [@name]
117
122
  }
@@ -1,35 +1,35 @@
1
1
  module EventHub
2
- EH_X_INBOUND = 'event_hub.inbound'
2
+ EH_X_INBOUND = "event_hub.inbound"
3
3
 
4
- STATUS_INITIAL = 0 # To be set when dispatcher needs to dispatch to first process step.
4
+ STATUS_INITIAL = 0 # To be set when dispatcher needs to dispatch to first process step.
5
5
 
6
- STATUS_SUCCESS = 200 # To be set to indicate successful processed message. Dispatcher will routes message to the next step.
6
+ STATUS_SUCCESS = 200 # To be set to indicate successful processed message. Dispatcher will routes message to the next step.
7
7
 
8
- STATUS_RETRY = 300 # To be set to trigger retry cycle controlled by the dispatcher
9
- STATUS_RETRY_PENDING = 301 # Set and used by the dispatcher only.
10
- # Set before putting the message into a retry queue.
11
- # Once message has been retried it will sent do the same step with status.code = STATUS_SUCCESS
8
+ STATUS_RETRY = 300 # To be set to trigger retry cycle controlled by the dispatcher
9
+ STATUS_RETRY_PENDING = 301 # Set and used by the dispatcher only.
10
+ # Set before putting the message into a retry queue.
11
+ # Once message has been retried it will sent do the same step with status.code = STATUS_SUCCESS
12
12
 
13
- STATUS_INVALID = 400 # To be set to indicate invalid message (not json, invalid Event Hub Message).
14
- # Dispatcher will publish message to the invalid queue.
13
+ STATUS_INVALID = 400 # To be set to indicate invalid message (not json, invalid Event Hub Message).
14
+ # Dispatcher will publish message to the invalid queue.
15
15
 
16
- STATUS_DEADLETTER = 500 # To be set by dispatcher, processor or channel adapters to indicate
17
- # that message needs to be dead-lettered. Rejected messages could miss the
18
- # status.code = STATUS_DEADLETTER due to the RabbitMQ deadletter exchange mechanism.
16
+ STATUS_DEADLETTER = 500 # To be set by dispatcher, processor or channel adapters to indicate
17
+ # that message needs to be dead-lettered. Rejected messages could miss the
18
+ # status.code = STATUS_DEADLETTER due to the RabbitMQ deadletter exchange mechanism.
19
19
 
20
- STATUS_SCHEDULE = 600 # To be set to trigger scheduler based on schedule block, proceses next process step
21
- STATUS_SCHEDULE_RETRY = 601 # To be set to trigger scheduler based on schedule block, retry actual process step
22
- STATUS_SCHEDULE_PENDING = 602 # Set and used by the dispatcher only. Set before putting the scheduled message to the schedule queue.
20
+ STATUS_SCHEDULE = 600 # To be set to trigger scheduler based on schedule block, proceses next process step
21
+ STATUS_SCHEDULE_RETRY = 601 # To be set to trigger scheduler based on schedule block, retry actual process step
22
+ STATUS_SCHEDULE_PENDING = 602 # Set and used by the dispatcher only. Set before putting the scheduled message to the schedule queue.
23
23
 
24
24
  STATUS_CODE_TRANSLATION = {
25
- STATUS_INITIAL => 'STATUS_INITIAL',
26
- STATUS_SUCCESS => 'STATUS_SUCCESS',
27
- STATUS_RETRY => 'STATUS_RETRY',
28
- STATUS_RETRY_PENDING => 'STATUS_RETRY_PENDING',
29
- STATUS_INVALID => 'STATUS_INVALID',
30
- STATUS_DEADLETTER => 'STATUS_DEADLETTER',
31
- STATUS_SCHEDULE => 'STATUS_SCHEDULE',
32
- STATUS_SCHEDULE_RETRY => 'STATUS_SCHEDULE_RETRY',
33
- STATUS_SCHEDULE_PENDING =>'STATUS_SCHEDULE_PENDING',
25
+ STATUS_INITIAL => "STATUS_INITIAL",
26
+ STATUS_SUCCESS => "STATUS_SUCCESS",
27
+ STATUS_RETRY => "STATUS_RETRY",
28
+ STATUS_RETRY_PENDING => "STATUS_RETRY_PENDING",
29
+ STATUS_INVALID => "STATUS_INVALID",
30
+ STATUS_DEADLETTER => "STATUS_DEADLETTER",
31
+ STATUS_SCHEDULE => "STATUS_SCHEDULE",
32
+ STATUS_SCHEDULE_RETRY => "STATUS_SCHEDULE_RETRY",
33
+ STATUS_SCHEDULE_PENDING => "STATUS_SCHEDULE_PENDING"
34
34
  }
35
35
  end
@@ -10,18 +10,18 @@ module HashExtensions
10
10
  # e.g. hash.get(%w(event_hub plate.queue1 retry_s))
11
11
  # "a" => { "b" => { "c" => { "value"}}}
12
12
  def get(arg)
13
- path = arg.is_a?(String) ? arg.split('.') : arg
13
+ path = arg.is_a?(String) ? arg.split(".") : arg
14
14
  path.inject(self, :[])
15
15
  end
16
16
 
17
17
  # set value from provided key path, e.h. hash.set('a.b.c','new value')
18
18
  # if overwrite is false, value will be set if it was nil previously
19
19
  def set(arg, value, overwrite = true)
20
- *key_path, last = arg.is_a?(String) ? arg.split('.') : arg
20
+ *key_path, last = arg.is_a?(String) ? arg.split(".") : arg
21
21
  if overwrite
22
- key_path.inject(self) { |h, key| h.key?(key) ? h[key] : h[key] = {} } [last] = value
22
+ key_path.inject(self) { |h, key| h.key?(key) ? h[key] : h[key] = {} } [last] = value
23
23
  else
24
- key_path.inject(self) { |h, key| h.key?(key) ? h[key] : h[key] = {} } [last] ||= value
24
+ key_path.inject(self) { |h, key| h.key?(key) ? h[key] : h[key] = {} } [last] ||= value
25
25
  end
26
26
  end
27
27
 
@@ -30,10 +30,10 @@ module HashExtensions
30
30
  def all_keys_with_path(parent = nil)
31
31
  a = []
32
32
  each do |k, v|
33
- if v.is_a?(Hash)
34
- a << v.all_keys_with_path([parent, k].compact.join('.'))
33
+ a << if v.is_a?(Hash)
34
+ v.all_keys_with_path([parent, k].compact.join("."))
35
35
  else
36
- a << [parent, k].compact.join('.').to_s
36
+ [parent, k].compact.join(".").to_s
37
37
  end
38
38
  end
39
39
  a.flatten
@@ -41,7 +41,7 @@ module HashExtensions
41
41
  end
42
42
 
43
43
  def self.included(receiver)
44
- receiver.extend ClassMethods
44
+ receiver.extend ClassMethods
45
45
  receiver.send :include, InstanceMethods
46
46
  end
47
47
  end
@@ -11,16 +11,16 @@ module EventHub
11
11
  # EventHub::NameSpace::DemoProcessor => name_space.demo_processor
12
12
  # NameSpace::Demo => name_space.demo
13
13
  def get_name_from_class(instance)
14
- instance.class.to_s.split('::').map do |element|
15
- next if element == 'EventHub'
16
- element.split(/(?=[A-Z])/).join('_').downcase
17
- end.compact.join('.')
14
+ instance.class.to_s.split("::").map { |element|
15
+ next if element == "EventHub"
16
+ element.split(/(?=[A-Z])/).join("_").downcase
17
+ }.compact.join(".")
18
18
  end
19
19
 
20
20
  def create_bunny_connection
21
21
  server = EventHub::Configuration.server
22
22
 
23
- protocol = 'amqp'
23
+ protocol = "amqp"
24
24
  connection_properties = {}
25
25
  connection_properties[:user] = server[:user]
26
26
  connection_properties[:pass] = server[:password]
@@ -28,7 +28,7 @@ module EventHub
28
28
 
29
29
  # inject bunny logs on request
30
30
  unless server[:show_bunny_logs]
31
- connection_properties[:logger] = Logger.new('/dev/null')
31
+ connection_properties[:logger] = Logger.new("/dev/null")
32
32
  end
33
33
 
34
34
  # we don't need it since reactors can deal with it
@@ -50,7 +50,7 @@ module EventHub
50
50
  end
51
51
 
52
52
  # Formats stamp into UTC format
53
- def now_stamp(now=nil)
53
+ def now_stamp(now = nil)
54
54
  now ||= Time.now
55
55
  now.utc.strftime("%Y-%m-%dT%H:%M:%S.%6NZ")
56
56
  end
@@ -3,10 +3,10 @@ module EventHub
3
3
  def self.logger
4
4
  unless @logger
5
5
  @logger = ::EventHub::Components::MultiLogger.new
6
- @logger.add_device(Logger.new(STDOUT))
6
+ @logger.add_device(Logger.new($stdout))
7
7
  @logger.add_device(
8
8
  EventHub::Components::Logger.logstash(Configuration.name,
9
- Configuration.environment)
9
+ Configuration.environment)
10
10
  )
11
11
  end
12
12
  @logger
@@ -4,29 +4,29 @@ module EventHub
4
4
  class Message
5
5
  include Helper
6
6
 
7
- VERSION = '1.0.0'.freeze
7
+ VERSION = "1.0.0".freeze
8
8
 
9
9
  # Headers that are required (value can be nil) in order to pass valid?
10
10
  REQUIRED_HEADERS = [
11
- 'message_id',
12
- 'version',
13
- 'created_at',
14
- 'origin.module_id',
15
- 'origin.type',
16
- 'origin.site_id',
17
- 'process.name',
18
- 'process.step_position',
19
- 'process.execution_id',
20
- 'status.retried_count',
21
- 'status.code',
22
- 'status.message'
11
+ "message_id",
12
+ "version",
13
+ "created_at",
14
+ "origin.module_id",
15
+ "origin.type",
16
+ "origin.site_id",
17
+ "process.name",
18
+ "process.step_position",
19
+ "process.execution_id",
20
+ "status.retried_count",
21
+ "status.code",
22
+ "status.message"
23
23
  ].freeze
24
24
 
25
25
  attr_accessor :header, :body, :raw, :vhost, :routing_key
26
26
 
27
27
  # Build accessors for all required headers
28
28
  REQUIRED_HEADERS.each do |header|
29
- name = header.tr('.', '_')
29
+ name = header.tr(".", "_")
30
30
 
31
31
  define_method(name) do
32
32
  self.header.get(header)
@@ -39,18 +39,18 @@ module EventHub
39
39
 
40
40
  def self.from_json(raw)
41
41
  data = JSON.parse(raw)
42
- Message.new(data.get('header'), data.get('body'), raw)
42
+ Message.new(data.get("header"), data.get("body"), raw)
43
43
  rescue => e
44
44
  Message.new(
45
45
  {
46
- 'status' =>
46
+ "status" =>
47
47
  {
48
- 'code' => STATUS_INVALID,
49
- 'message' => "JSON parse error: #{e}"
48
+ "code" => STATUS_INVALID,
49
+ "message" => "JSON parse error: #{e}"
50
50
  }
51
51
  },
52
52
  {
53
- 'original_message_base64_encoded' => Base64.encode64(raw)
53
+ "original_message_base64_encoded" => Base64.encode64(raw)
54
54
  },
55
55
  raw
56
56
  )
@@ -58,33 +58,33 @@ module EventHub
58
58
 
59
59
  def initialize(header = nil, body = nil, raw = nil)
60
60
  @header = header || {}
61
- @body = body || {}
62
- @raw = raw
61
+ @body = body || {}
62
+ @raw = raw
63
63
 
64
64
  # set message defaults, that we have required headers
65
- @header.set('message_id', UUIDTools::UUID.timestamp_create.to_s, false)
66
- @header.set('version', VERSION, false)
67
- @header.set('created_at', now_stamp, false)
65
+ @header.set("message_id", UUIDTools::UUID.timestamp_create.to_s, false)
66
+ @header.set("version", VERSION, false)
67
+ @header.set("created_at", now_stamp, false)
68
68
 
69
- @header.set('origin.module_id', 'undefined', false)
70
- @header.set('origin.type', 'undefined', false)
71
- @header.set('origin.site_id', 'undefined', false)
69
+ @header.set("origin.module_id", "undefined", false)
70
+ @header.set("origin.type", "undefined", false)
71
+ @header.set("origin.site_id", "undefined", false)
72
72
 
73
- @header.set('process.name', 'undefined', false)
74
- @header.set('process.execution_id',
75
- UUIDTools::UUID.timestamp_create.to_s, false)
76
- @header.set('process.step_position', 0, false)
73
+ @header.set("process.name", "undefined", false)
74
+ @header.set("process.execution_id",
75
+ UUIDTools::UUID.timestamp_create.to_s, false)
76
+ @header.set("process.step_position", 0, false)
77
77
 
78
- @header.set('status.retried_count', 0, false)
79
- @header.set('status.code', STATUS_INITIAL, false)
80
- @header.set('status.message', '', false)
78
+ @header.set("status.retried_count", 0, false)
79
+ @header.set("status.code", STATUS_INITIAL, false)
80
+ @header.set("status.message", "", false)
81
81
  end
82
82
 
83
83
  def valid?
84
84
  # check for existence and defined value
85
85
  REQUIRED_HEADERS.all? do |key|
86
86
  @header.all_keys_with_path.include?(key) &&
87
- !send(key.tr('.', '_').to_sym).nil?
87
+ !send(key.tr(".", "_").to_sym).nil?
88
88
  end
89
89
  end
90
90
 
@@ -121,11 +121,11 @@ module EventHub
121
121
  end
122
122
 
123
123
  def to_json
124
- { 'header' => header, 'body' => body }.to_json
124
+ {"header" => header, "body" => body}.to_json
125
125
  end
126
126
 
127
127
  def to_s
128
- 'Msg: process '\
128
+ "Msg: process "\
129
129
  "[#{process_name}, #{process_step_position}, #{process_execution_id}]"\
130
130
  ", status [#{status_code},#{status_message},#{status_retried_count}]"
131
131
  end
@@ -135,20 +135,20 @@ module EventHub
135
135
  def copy(status_code = STATUS_SUCCESS)
136
136
  # use Marshal dump and load to make a deep object copy
137
137
  copied_header = Marshal.load(Marshal.dump(header))
138
- copied_body = Marshal.load(Marshal.dump(body))
138
+ copied_body = Marshal.load(Marshal.dump(body))
139
139
 
140
- copied_header.set('message_id', UUIDTools::UUID.timestamp_create.to_s)
141
- copied_header.set('created_at', now_stamp)
142
- copied_header.set('status.code', status_code)
140
+ copied_header.set("message_id", UUIDTools::UUID.timestamp_create.to_s)
141
+ copied_header.set("created_at", now_stamp)
142
+ copied_header.set("status.code", status_code)
143
143
 
144
144
  Message.new(copied_header, copied_body)
145
145
  end
146
146
 
147
147
  def append_to_execution_history(processor_name)
148
- header.set('execution_history', []) unless \
149
- header.get('execution_history')
150
- header.get('execution_history') << \
151
- { 'processor' => processor_name, 'timestamp' => now_stamp }
148
+ header.set("execution_history", []) unless \
149
+ header.get("execution_history")
150
+ header.get("execution_history") << \
151
+ {"processor" => processor_name, "timestamp" => now_stamp}
152
152
  end
153
153
 
154
154
  def self.translate_status_code(code)