Class: Mihari::Analyzers::Base

Inherits:
Mihari::Actor show all
Defined in:
lib/mihari/analyzers/base.rb

Overview

Base class for analyzers

Constant Summary

Constants included from Concerns::Retriable

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

Instance Attribute Summary collapse

Attributes inherited from Mihari::Actor

#options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Mihari::Actor

configuration_keys, key, key_aliases, keys, #retry_exponential_backoff, #retry_interval, #retry_times, #timeout, type, #validate_configuration!

Methods included from Concerns::Retriable

#retry_on_error

Methods included from Concerns::Configurable

#configuration_keys?, #configured?

Constructor Details

#initialize(query, options: nil) ⇒ Base

Returns a new instance of Base.

Parameters:

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


16
17
18
19
20
# File 'lib/mihari/analyzers/base.rb', line 16

def initialize(query, options: nil)
  super(options:)

  @query = query
end

Instance Attribute Details

#queryString (readonly)

Returns:

  • (String)


10
11
12
# File 'lib/mihari/analyzers/base.rb', line 10

def query
  @query
end

Class Method Details

.from_params(params) ⇒ Mihari::Analyzers::Base

Initialize an analyzer by query params

Parameters:

  • params (Hash)

Returns:



119
120
121
122
# File 'lib/mihari/analyzers/base.rb', line 119

def from_params(params)
  query = params.delete(:query)
  new(query, **params)
end

.inherited(child) ⇒ Object



124
125
126
127
# File 'lib/mihari/analyzers/base.rb', line 124

def inherited(child)
  super
  Mihari.analyzers << child
end

Instance Method Details

#artifactsArray<String>, Array<Mihari::Models::Artifact>

Returns:

Raises:

  • (NotImplementedError)


51
52
53
# File 'lib/mihari/analyzers/base.rb', line 51

def artifacts
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end

#callArray<Mihari::Models::Artifact>

Returns:



76
77
78
# File 'lib/mihari/analyzers/base.rb', line 76

def call
  normalized_artifacts
end

#ignore_error?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/mihari/analyzers/base.rb', line 39

def ignore_error?
  options[:ignore_error] || Mihari.config.ignore_error
end

#normalized_artifactsArray<Mihari::Models::Artifact>

Normalize artifacts

  • Convert data (string) into an artifact

  • Reject an invalid artifact

Returns:



62
63
64
65
66
67
68
69
70
71
# File 'lib/mihari/analyzers/base.rb', line 62

def normalized_artifacts
  artifacts.compact.sort.map do |artifact|
    # No need to set data_type manually
    # It is set automatically in #initialize
    (artifact.is_a?(Models::Artifact) ? artifact : Models::Artifact.new(data: artifact)).tap do |normalized|
      normalized.source = self.class.key
      normalized.query = query
    end
  end.select(&:valid?).uniq(&:data)
end

#pagination_intervalInteger

Returns:

  • (Integer)


25
26
27
# File 'lib/mihari/analyzers/base.rb', line 25

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

#pagination_limitInteger

Returns:

  • (Integer)


32
33
34
# File 'lib/mihari/analyzers/base.rb', line 32

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

#parallel?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/mihari/analyzers/base.rb', line 46

def parallel?
  options[:parallel] || Mihari.config.analyzer_parallelism
end

#resultObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/mihari/analyzers/base.rb', line 80

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

  return result if result.success?

  # Wrap failure with AnalyzerError to explicitly name a failed analyzer
  error = AnalyzerError.new(result.failure.message, self.class.key, cause: result.failure)
  return Failure(error) unless ignore_error?

  # Return Success if ignore_error? is true with logging
  Mihari.logger.warn("Analyzer:#{self.class.key} with #{truncated_query} failed - #{result.failure}")
  Success([])
end

#truncated_queryString

Truncate query for logging

Returns:

  • (String)


107
108
109
# File 'lib/mihari/analyzers/base.rb', line 107

def truncated_query
  query.truncate(32)
end