eventhub-processor2 1.4.0 → 1.9.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.
@@ -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)