Class: Mihari::Actor

Inherits:
Object
  • Object
show all
Includes:
Concerns::Configurable, Concerns::Retriable
Defined in:
lib/mihari/actor.rb

Overview

Yet another base service class for Analyzer, Emitter and Enricher

Constant Summary

Constants included from Concerns::Retriable

Concerns::Retriable::DEFAULT_CONDITION, Concerns::Retriable::RETRIABLE_ERRORS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Concerns::Retriable

#retry_on_error

Methods included from Concerns::Configurable

#configuration_keys?, #configured?

Constructor Details

#initialize(options: nil) ⇒ Actor

Returns a new instance of Actor.

Parameters:

  • options (Hash, nil) (defaults to: nil)


19
20
21
22
23
# File 'lib/mihari/actor.rb', line 19

def initialize(options: nil)
  super()

  @options = options || {}
end

Instance Attribute Details

#optionsHash (readonly)

Returns:

  • (Hash)


14
15
16
# File 'lib/mihari/actor.rb', line 14

def options
  @options
end

Class Method Details

.configuration_keysObject



96
97
98
99
100
101
102
103
# File 'lib/mihari/actor.rb', line 96

def configuration_keys
  # Automatically generate configuration keys based on key
  # For example,
  # - Shodan analyzer's key is "shodan"
  # - Mihari.config has "shodan_api_key"
  # - Select "shodan_api_key" by using "#{key}_" prefix
  Mihari.config.keys.select { |config_key| config_key.start_with?("#{key}_") }
end

.keyString

Returns:

  • (String)


78
79
80
# File 'lib/mihari/actor.rb', line 78

def key
  to_s.split("::").last.downcase
end

.key_aliasesArray<String>?

Returns:

  • (Array<String>, nil)


85
86
87
# File 'lib/mihari/actor.rb', line 85

def key_aliases
  nil
end

.keysArray<String>

Returns:

  • (Array<String>)


92
93
94
# File 'lib/mihari/actor.rb', line 92

def keys
  ([key] + [key_aliases]).flatten.compact.map(&:downcase)
end

.typeObject



105
106
107
108
109
110
111
# File 'lib/mihari/actor.rb', line 105

def type
  return "analyzer" if ancestors.include?(Mihari::Analyzers::Base)
  return "emitter" if ancestors.include?(Mihari::Emitters::Base)
  return "enricher" if ancestors.include?(Mihari::Enrichers::Base)

  nil
end

Instance Method Details

#call(*args, **kwargs) ⇒ Object

Raises:

  • (NotImplementedError)


62
63
64
# File 'lib/mihari/actor.rb', line 62

def call(*args, **kwargs)
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end

#resultObject



66
67
68
69
70
71
72
# File 'lib/mihari/actor.rb', line 66

def result(...)
  Try[StandardError] do
    retry_on_error(times: retry_times, interval: retry_interval, exponential_backoff: retry_exponential_backoff) do
      call(...)
    end
  end.to_result
end

#retry_exponential_backoffBoolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/mihari/actor.rb', line 35

def retry_exponential_backoff
  options[:retry_exponential_backoff] || Mihari.config.retry_exponential_backoff
end

#retry_intervalInteger

Returns:

  • (Integer)


28
29
30
# File 'lib/mihari/actor.rb', line 28

def retry_interval
  options[:retry_interval] || Mihari.config.retry_interval
end

#retry_timesInteger

Returns:

  • (Integer)


42
43
44
# File 'lib/mihari/actor.rb', line 42

def retry_times
  options[:retry_times] || Mihari.config.retry_times
end

#timeoutInteger?

Returns:

  • (Integer, nil)


49
50
51
# File 'lib/mihari/actor.rb', line 49

def timeout
  options[:timeout]
end

#validate_configuration!Object

Raises:



53
54
55
56
57
58
59
60
# File 'lib/mihari/actor.rb', line 53

def validate_configuration!
  return if configured?

  message = "#{self.class.type.capitalize}:#{self.class.key} is not configured correctly"
  detail = self.class.configuration_keys.map { |key| "#{key.upcase} is missing" }

  raise ConfigurationError.new(message, detail)
end