connectors_service 8.7.0.0.pre.20221117T004928Z → 8.11.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/config/connectors.yml +10 -8
  3. data/lib/app/config.rb +6 -1
  4. data/lib/app/console_app.rb +1 -1
  5. data/lib/app/dispatcher.rb +18 -3
  6. data/lib/connectors/base/connector.rb +39 -22
  7. data/lib/connectors/crawler/scheduler.rb +36 -0
  8. data/lib/connectors/example/connector.rb +2 -2
  9. data/lib/connectors/example/example_advanced_snippet_validator.rb +4 -3
  10. data/lib/connectors/gitlab/connector.rb +4 -4
  11. data/lib/connectors/gitlab/gitlab_advanced_snippet_validator.rb +8 -10
  12. data/lib/{connectors_app/// → connectors/job_trigger_method.rb} +6 -5
  13. data/lib/connectors/mongodb/connector.rb +66 -56
  14. data/lib/connectors/mongodb/mongo_advanced_snippet_against_schema_validator.rb +2 -2
  15. data/lib/connectors/mongodb/mongo_advanced_snippet_schema.rb +3 -2
  16. data/lib/connectors/mongodb/mongo_advanced_snippet_snake_case_transformer.rb +49 -0
  17. data/lib/connectors/registry.rb +1 -1
  18. data/lib/connectors/tolerable_error_helper.rb +5 -1
  19. data/lib/connectors_utility.rb +6 -3
  20. data/lib/core/configuration.rb +13 -1
  21. data/lib/core/connector_job.rb +48 -7
  22. data/lib/core/connector_settings.rb +52 -20
  23. data/lib/core/elastic_connector_actions.rb +54 -38
  24. data/lib/core/filtering/advanced_snippet/advanced_snippet_against_schema_validator.rb +32 -0
  25. data/lib/core/filtering/advanced_snippet/advanced_snippet_validator.rb +27 -0
  26. data/lib/core/filtering/filter_validator.rb +103 -0
  27. data/lib/{connectors/base/advanced_snippet_against_schema_validator.rb → core/filtering/hash_against_schema_validator.rb} +58 -44
  28. data/lib/core/filtering/post_process_engine.rb +2 -2
  29. data/lib/core/filtering/processing_stage.rb +20 -0
  30. data/lib/core/filtering/{simple_rule.rb → simple_rules/simple_rule.rb} +34 -1
  31. data/lib/core/filtering/simple_rules/simple_rules_parser.rb +44 -0
  32. data/lib/core/filtering/simple_rules/validation/no_conflicting_policies_rules_validator.rb +47 -0
  33. data/lib/core/filtering/simple_rules/validation/simple_rules_schema.rb +68 -0
  34. data/lib/core/filtering/simple_rules/validation/simple_rules_validator.rb +25 -0
  35. data/lib/core/filtering/simple_rules/validation/single_rule_against_schema_validator.rb +37 -0
  36. data/lib/core/filtering/transform/filter_transformer.rb +26 -0
  37. data/lib/core/filtering/transform/filter_transformer_facade.rb +61 -0
  38. data/lib/core/filtering/transform/transformation_target.rb +10 -0
  39. data/lib/core/filtering/validation_job_runner.rb +1 -3
  40. data/lib/core/filtering.rb +5 -3
  41. data/lib/core/job_cleanup.rb +66 -0
  42. data/lib/core/jobs/consumer.rb +62 -64
  43. data/lib/core/jobs/producer.rb +3 -0
  44. data/lib/core/scheduler.rb +67 -52
  45. data/lib/core/sync_job_runner.rb +170 -83
  46. data/lib/core.rb +1 -0
  47. data/lib/utility/bulk_queue.rb +1 -1
  48. data/lib/utility/constants.rb +0 -2
  49. data/lib/utility/error_monitor.rb +26 -5
  50. data/lib/utility/es_client.rb +4 -0
  51. data/lib/utility/filtering.rb +4 -0
  52. metadata +32 -21
  53. data/lib/connectors/base/advanced_snippet_validator.rb +0 -34
  54. data/lib/connectors/base/simple_rules_parser.rb +0 -42
  55. data/lib/connectors/mongodb/mongo_rules_parser.rb +0 -81
@@ -7,83 +7,90 @@
7
7
 
8
8
  require 'active_support/core_ext/hash'
9
9
  require 'utility/logger'
10
- require 'connectors/base/advanced_snippet_validator'
11
- require 'core/filtering/validation_status'
12
10
 
13
- module Connectors
14
- module Base
15
- class AdvancedSnippetAgainstSchemaValidator < Connectors::Base::AdvancedSnippetValidator
11
+ module Core
12
+ module Filtering
13
+ class SchemaValidator
16
14
 
17
15
  MAX_RECURSION_DEPTH = 50
18
- ADVANCED_SNIPPET_ID = 'advanced_snippet'
19
16
 
20
- def initialize(advanced_snippet, schema)
21
- super(advanced_snippet)
17
+ def initialize(schema: {}, payload: {}, error_id: '')
22
18
  @schema = schema
19
+ @payload = payload
20
+ @error_id = error_id
23
21
  end
24
22
 
25
- def is_snippet_valid?
26
- validation_result = validate_against_schema(@schema, @advanced_snippet)
27
- log_validation_result(validation_result)
28
- validation_result
29
- end
30
-
31
- private
32
-
33
- def validate_against_schema(config_schema, advanced_snippet, recursion_depth = 0)
23
+ def validate_against_schema(schema = @schema, payload = @payload, recursion_depth = 0)
34
24
  # Prevent unintentional/intentional SystemStackErrors/crashes
35
25
  return unexpected_error if exceeded_recursion_depth?(recursion_depth)
36
26
 
37
- return valid_snippet if config_schema.nil? || config_schema.empty?
27
+ return valid_snippet unless schema.present?
38
28
 
39
- schema_fields = config_schema[:fields].is_a?(Hash) ? config_schema.dig(:fields, :values) : config_schema[:fields]
40
- snippet_field_names = advanced_snippet&.keys&.map(&:to_s)
29
+ schema_fields = schema[:fields].is_a?(Hash) ? schema.dig(:fields, :values) : schema[:fields]
30
+ snippet_field_names = payload&.keys&.map(&:to_s)
41
31
  schema_field_names = schema_fields.map { |field| field[:name] }
42
32
 
43
33
  return unexpected_field(schema_field_names, snippet_field_names) if unexpected_field_present?(snippet_field_names, schema_field_names)
44
34
 
45
- return fields_constraint_violation(config_schema[:fields]) if fields_constraints_violated?(config_schema, advanced_snippet)
35
+ return fields_constraint_violation(schema[:fields]) if fields_constraints_violated?(schema[:fields], payload)
46
36
 
47
37
  schema_fields.each do |field|
48
38
  name = field[:name]
49
39
  type = field[:type]
50
40
  optional = field[:optional] || false
51
41
 
52
- snippet_field_value = advanced_snippet.with_indifferent_access[name]
42
+ snippet_field_value = payload.nil? ? nil : payload.with_indifferent_access[name]
53
43
 
54
44
  next if optional && (snippet_field_value.nil? || !snippet_field_value.present?)
55
45
 
56
- return wrong_names(snippet_field_names, name) unless snippet_field_names.include?(name)
46
+ return required_value_missing(name) if is_required_value_missing?(snippet_field_value)
57
47
 
58
- return wrong_type(name, type, snippet_field_value) if type_error_present?(type, snippet_field_value)
48
+ type_error_present, error_message = type_error_present?(name, type, snippet_field_value)
49
+
50
+ return wrong_type(error_message) if type_error_present
59
51
 
60
52
  if field[:fields].present?
61
53
  validation_result = validate_against_schema(field, snippet_field_value, recursion_depth + 1)
62
54
 
63
- return validation_result unless validation_result[:is_valid]
55
+ return validation_result unless validation_result[:state] == Core::Filtering::ValidationStatus::VALID
64
56
  end
65
57
  end
66
58
 
67
59
  valid_snippet
68
60
  end
69
61
 
70
- def fields_constraints_violated?(config_schema, advanced_snippet)
71
- return false unless config_schema[:fields].is_a?(Hash)
62
+ def fields_constraints_violated?(fields, payload)
63
+ return false if !fields.present? || !fields.is_a?(Hash)
72
64
 
73
- constraints = config_schema.dig(:fields, :constraints)
65
+ constraints = fields[:constraints]
74
66
  constraints = constraints.is_a?(Array) ? constraints : [constraints]
75
67
 
76
68
  constraints.each do |constraint|
77
- return true unless constraint.call(advanced_snippet)
69
+ return true unless constraint.call(payload)
78
70
  end
79
71
 
80
72
  false
81
73
  end
82
74
 
83
- def type_error_present?(schema_type, snippet_value)
84
- return !schema_type.call(snippet_value) if schema_type.is_a?(Proc)
75
+ def type_error_present?(field_name, schema_type, actual_value)
76
+ if schema_type.is_a?(Proc)
77
+ result = schema_type.call(actual_value)
78
+
79
+ # could already have a custom error message
80
+ if result.is_a?(Array)
81
+ is_valid, error_msg = result
82
+
83
+ return !is_valid, error_msg
84
+ end
85
+
86
+ # could only return a single boolean
87
+ return !result, 'Custom type matcher validation failed.'
88
+ end
89
+
90
+ error_msg = "Expected field type '#{schema_type}' for field '#{field_name}', but got value '#{actual_value.inspect}' of type '#{actual_value.class}'."
91
+ return true, error_msg unless actual_value.is_a?(schema_type)
85
92
 
86
- !snippet_value.is_a?(schema_type)
93
+ false
87
94
  end
88
95
 
89
96
  def exceeded_recursion_depth?(recursion_depth)
@@ -96,12 +103,18 @@ module Connectors
96
103
  end
97
104
 
98
105
  def unexpected_field_present?(actual_field_names, expected_field_names)
106
+ return false unless actual_field_names.present?
107
+
99
108
  difference = actual_field_names - expected_field_names
100
109
 
101
110
  # we have field names, which we didn't expect
102
111
  !difference.empty?
103
112
  end
104
113
 
114
+ def is_required_value_missing?(snippet_field_value)
115
+ !snippet_field_value.present?
116
+ end
117
+
105
118
  def valid_snippet
106
119
  {
107
120
  :state => Core::Filtering::ValidationStatus::VALID,
@@ -109,37 +122,37 @@ module Connectors
109
122
  }
110
123
  end
111
124
 
112
- def unexpected_field(expected_fields, actual_fields)
125
+ def required_value_missing(field)
113
126
  {
114
127
  :state => Core::Filtering::ValidationStatus::INVALID,
115
128
  :errors => [
116
129
  {
117
- :ids => [ADVANCED_SNIPPET_ID],
118
- :messages => ["Encountered unexpected fields '#{actual_fields}'. Expected: '#{expected_fields}'."]
130
+ :ids => [@error_id],
131
+ :messages => ["Required value missing for field '#{field}'."]
119
132
  }
120
133
  ]
121
134
  }
122
135
  end
123
136
 
124
- def wrong_type(field_name, expected_type, actual_value)
137
+ def unexpected_field(expected_fields, actual_fields)
125
138
  {
126
139
  :state => Core::Filtering::ValidationStatus::INVALID,
127
140
  :errors => [
128
141
  {
129
- :ids => [ADVANCED_SNIPPET_ID],
130
- :messages => ["Expected field type '#{expected_type.is_a?(Proc) ? 'custom matcher' : expected_type}' for field '#{field_name}', but got value '#{actual_value.inspect}' of type '#{actual_value.class}'."]
142
+ :ids => [@error_id],
143
+ :messages => ["Encountered unexpected fields '#{actual_fields}'. Expected: '#{expected_fields}'."]
131
144
  }
132
145
  ]
133
146
  }
134
147
  end
135
148
 
136
- def wrong_names(actual_field_names, expected_field_name)
149
+ def wrong_type(error_message)
137
150
  {
138
151
  :state => Core::Filtering::ValidationStatus::INVALID,
139
152
  :errors => [
140
153
  {
141
- :ids => [ADVANCED_SNIPPET_ID],
142
- :messages => ["Expected field name '#{expected_field_name}', but got #{actual_field_names}."]
154
+ :ids => [@error_id],
155
+ :messages => [error_message]
143
156
  }
144
157
  ]
145
158
  }
@@ -150,8 +163,8 @@ module Connectors
150
163
  :state => Core::Filtering::ValidationStatus::INVALID,
151
164
  :errors => [
152
165
  {
153
- :ids => [ADVANCED_SNIPPET_ID],
154
- :messages => ["A fields constraint was violated for fields: '#{fields[:values].map { |v| v[:name] }}'. Check advanced snippet field constraints."]
166
+ :ids => [@error_id],
167
+ :messages => ["A fields constraint was violated for fields: '#{fields[:values].map { |v| v[:name] }}'."]
155
168
  }
156
169
  ]
157
170
  }
@@ -162,12 +175,13 @@ module Connectors
162
175
  :state => Core::Filtering::ValidationStatus::INVALID,
163
176
  :errors => [
164
177
  {
165
- :ids => [ADVANCED_SNIPPET_ID],
178
+ :ids => [@error_id],
166
179
  :messages => ['Unexpected error. Check logs for details.']
167
180
  }
168
181
  ]
169
182
  }
170
183
  end
184
+
171
185
  end
172
186
  end
173
187
  end
@@ -14,8 +14,8 @@ module Core
14
14
  class PostProcessEngine
15
15
  attr_reader :rules
16
16
 
17
- def initialize(job_description)
18
- @rules = ordered_rules(job_description.dig('connector', 'filtering'))
17
+ def initialize(filtering)
18
+ @rules = ordered_rules(filtering)
19
19
  end
20
20
 
21
21
  def process(document)
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+ # frozen_string_literal: true
7
+
8
+ module Core
9
+ module Filtering
10
+ class ProcessingStage
11
+ PRE = 'pre-processing'
12
+ POST = 'post-processing'
13
+
14
+ ALL = [
15
+ PRE,
16
+ POST
17
+ ]
18
+ end
19
+ end
20
+ end
@@ -16,6 +16,11 @@ module Core
16
16
  class Policy
17
17
  INCLUDE = 'include'
18
18
  EXCLUDE = 'exclude'
19
+
20
+ POLICIES = [
21
+ INCLUDE,
22
+ EXCLUDE
23
+ ]
19
24
  end
20
25
 
21
26
  class Rule
@@ -26,6 +31,16 @@ module Core
26
31
  CONTAINS = 'contains'
27
32
  LESS_THAN = '<'
28
33
  GREATER_THAN = '>'
34
+
35
+ RULES = [
36
+ REGEX,
37
+ EQUALS,
38
+ STARTS_WITH,
39
+ ENDS_WITH,
40
+ CONTAINS,
41
+ LESS_THAN,
42
+ GREATER_THAN
43
+ ]
29
44
  end
30
45
 
31
46
  attr_reader :policy, :field, :rule, :value, :id
@@ -123,6 +138,18 @@ module Core
123
138
  @rule_hash
124
139
  end
125
140
 
141
+ def try_coerce_value
142
+ coerced = to_float(value)
143
+ begin
144
+ coerced = to_date(value) if coerced.is_a?(String)
145
+ rescue ArgumentError
146
+ coerced = to_bool(value) if coerced.is_a?(String)
147
+ end
148
+ coerced
149
+ rescue StandardError
150
+ value
151
+ end
152
+
126
153
  private
127
154
 
128
155
  def to_bool(str)
@@ -134,7 +161,13 @@ module Core
134
161
  def to_date(str)
135
162
  DateTime.parse(str)
136
163
  rescue ArgumentError
137
- Time.at(str.to_i) # try with it as an int string of millis
164
+ Time.at(Integer(value)) # try with it as an int string of millis
165
+ end
166
+
167
+ def to_float(value)
168
+ Float(value)
169
+ rescue StandardError
170
+ value
138
171
  end
139
172
  end
140
173
  end
@@ -0,0 +1,44 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+ # frozen_string_literal: true
7
+
8
+ require 'active_support/core_ext/hash/indifferent_access'
9
+ require 'active_support/core_ext/object/blank'
10
+ require 'core/filtering/simple_rules/simple_rule'
11
+
12
+ module Core
13
+ module Filtering
14
+ module SimpleRules
15
+ class SimpleRulesParser
16
+ def initialize(rules)
17
+ @rules = (rules || []).map(&:with_indifferent_access).filter { |r| r[:id] != 'DEFAULT' }.sort_by { |r| r[:order] }
18
+ end
19
+
20
+ def parse
21
+ merge_rules(@rules.map do |rule_hash|
22
+ rule = Core::Filtering::SimpleRule.new(rule_hash)
23
+ unless rule.is_include? || rule.is_exclude?
24
+ raise "Unknown policy: #{rule.policy}"
25
+ end
26
+ parse_rule(rule)
27
+ end)
28
+ end
29
+
30
+ private
31
+
32
+ # merge all rules into a filter object or array
33
+ # in a base case, does no transformations
34
+ def merge_rules(rules)
35
+ rules || []
36
+ end
37
+
38
+ def parse_rule(_rule)
39
+ raise 'Not implemented'
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,47 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+ # frozen_string_literal: true
7
+
8
+ require 'core/filtering/simple_rules/validation/simple_rules_validator'
9
+ require 'core/filtering/validation_status'
10
+
11
+ module Core
12
+ module Filtering
13
+ module SimpleRules
14
+ module Validation
15
+ class NoConflictingPoliciesRulesValidator < Core::Filtering::SimpleRules::Validation::SimpleRulesValidator
16
+
17
+ def are_rules_valid
18
+ rule_field_value_to_policy = {}
19
+
20
+ @rules.each do |simple_rule|
21
+ rule_field_value = simple_rule.slice('rule', 'field', 'value')
22
+ policy = simple_rule['policy']
23
+
24
+ return conflicting_rules(rule_field_value) if rule_field_value_to_policy.key?(rule_field_value)
25
+
26
+ rule_field_value_to_policy[rule_field_value] = policy
27
+ end
28
+
29
+ { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
30
+ end
31
+
32
+ private
33
+
34
+ def conflicting_rules(rule_type_value)
35
+ {
36
+ :state => Core::Filtering::ValidationStatus::INVALID,
37
+ :errors => [
38
+ :ids => [SIMPLE_RULES_ID],
39
+ :messages => ["Two simple rules with same rule (#{rule_type_value['rule']}), field (#{rule_type_value['field']}), value (#{rule_type_value['value']}) and conflicting policies detected."]
40
+ ]
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,68 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+ # frozen_string_literal: true
7
+
8
+ require 'core/filtering/simple_rules/simple_rule'
9
+
10
+ module Core
11
+ module Filtering
12
+ module SimpleRules
13
+ module Validation
14
+ DEFAULT_RULE_ID = 'DEFAULT'
15
+
16
+ ALLOWED_VALUE_TYPES = ->(rule_value) { rule_value.is_a?(String) || rule_value.is_a?(Integer) || rule_value.is_a?(TrueClass) || rule_value.is_a?(FalseClass) }
17
+ MATCH_ALL_REGEX_NOT_ALLOWED = ->(simple_rule) { simple_rule['id'] == DEFAULT_RULE_ID || !(simple_rule['rule'] == Core::Filtering::SimpleRule::Rule::REGEX && (simple_rule['value'] == '(.*)' || simple_rule['value'] == '.*')) }
18
+
19
+ SINGLE_RULE_SCHEMA = {
20
+ :fields => {
21
+ :constraints => [MATCH_ALL_REGEX_NOT_ALLOWED],
22
+ :values => [
23
+ {
24
+ :name => 'id',
25
+ :type => String,
26
+ :optional => false
27
+ },
28
+ {
29
+ :name => 'field',
30
+ :type => String,
31
+ :optional => false
32
+ },
33
+ {
34
+ :name => 'value',
35
+ :type => ALLOWED_VALUE_TYPES,
36
+ :optional => false
37
+ },
38
+ {
39
+ :name => 'policy',
40
+ :type => ->(policy) { Core::Filtering::SimpleRule::Policy::POLICIES.include?(policy) },
41
+ :optional => false
42
+ },
43
+ {
44
+ :name => 'rule',
45
+ :type => ->(rule) { Core::Filtering::SimpleRule::Rule::RULES.include?(rule) },
46
+ :optional => false
47
+ },
48
+ {
49
+ :name => 'order',
50
+ :type => ->(order) { order.is_a?(Integer) && order >= 0 },
51
+ },
52
+ {
53
+ :name => 'updated_at',
54
+ :type => String,
55
+ :optional => true
56
+ },
57
+ {
58
+ :name => 'created_at',
59
+ :type => String,
60
+ :optional => true
61
+ }
62
+ ]
63
+ }
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,25 @@
1
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2
+ # or more contributor license agreements. Licensed under the Elastic License;
3
+ # you may not use this file except in compliance with the Elastic License.
4
+ #
5
+ # frozen_string_literal: true
6
+
7
+ module Core
8
+ module Filtering
9
+ module SimpleRules
10
+ module Validation
11
+ SIMPLE_RULES_ID = 'simple_rules'
12
+
13
+ class SimpleRulesValidator
14
+ def initialize(rules)
15
+ @rules = rules || []
16
+ end
17
+
18
+ def are_rules_valid
19
+ raise 'Simple rules validation not implemented'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+ # frozen_string_literal: true
7
+
8
+ require 'core/filtering/simple_rules/validation/simple_rules_validator'
9
+ require 'core/filtering/hash_against_schema_validator'
10
+ require 'core/filtering/simple_rules/validation/simple_rules_schema'
11
+
12
+ module Core
13
+ module Filtering
14
+ module SimpleRules
15
+ module Validation
16
+ class SingleRuleAgainstSchemaValidator < Core::Filtering::SimpleRules::Validation::SimpleRulesValidator
17
+
18
+ def initialize(rules, schema = Core::Filtering::SimpleRules::Validation::SINGLE_RULE_SCHEMA)
19
+ super(rules)
20
+ @schema = schema
21
+ @schema_validator = SchemaValidator.new(error_id: SIMPLE_RULES_ID)
22
+ end
23
+
24
+ def are_rules_valid
25
+ @rules.each do |rule|
26
+ validation_result = @schema_validator.validate_against_schema(@schema, rule)
27
+ return validation_result unless validation_result[:state] == Core::Filtering::ValidationStatus::VALID
28
+ end
29
+
30
+ { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+
7
+ # frozen_string_literal: true
8
+
9
+ module Core
10
+ module Filtering
11
+ module Transform
12
+ class FilterTransformer
13
+
14
+ def initialize(filter = {}, transformation = (->(_filter) { filter }))
15
+ @filter = filter
16
+ @transformation = transformation
17
+ end
18
+
19
+ def transform
20
+ @transformation.call(@filter)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,61 @@
1
+ #
2
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ # or more contributor license agreements. Licensed under the Elastic License;
4
+ # you may not use this file except in compliance with the Elastic License.
5
+ #
6
+
7
+ # frozen_string_literal: true
8
+
9
+ require 'core/filtering/transform/transformation_target'
10
+ require 'core/filtering/transform/filter_transformer'
11
+
12
+ module Core
13
+ module Filtering
14
+ module Transform
15
+ class FilterTransformerFacade < Core::Filtering::Transform::FilterTransformer
16
+
17
+ def initialize(filter = {},
18
+ filter_transformers = {
19
+ Core::Filtering::Transform::TransformationTarget::ADVANCED_SNIPPET => [],
20
+ Core::Filtering::Transform::TransformationTarget::RULES => [],
21
+ })
22
+ super(filter)
23
+
24
+ rule_transformer_classes = filter_transformers[Core::Filtering::Transform::TransformationTarget::RULES]
25
+ snippet_transformer_classes = filter_transformers[Core::Filtering::Transform::TransformationTarget::ADVANCED_SNIPPET]
26
+
27
+ @rule_transformers = rule_transformer_classes.is_a?(Array) ? rule_transformer_classes : [rule_transformer_classes]
28
+ @snippet_transformers = snippet_transformer_classes.is_a?(Array) ? snippet_transformer_classes : [snippet_transformer_classes]
29
+
30
+ @facade = FilterTransformer.new(filter, execute_rule_and_snippet_transformations)
31
+ end
32
+
33
+ def transform
34
+ @facade.transform
35
+ end
36
+
37
+ private
38
+
39
+ def execute_rule_and_snippet_transformations
40
+ lambda do |filter|
41
+ rules = filter[:rules]
42
+ advanced_snippet = filter[:advanced_snippet]
43
+
44
+ {
45
+ :rules => call_transformers(@rule_transformers, rules),
46
+ :advanced_snippet => call_transformers(@snippet_transformers, advanced_snippet)
47
+ }
48
+ end
49
+ end
50
+
51
+ def call_transformers(transformer_classes, payload)
52
+ transformer_classes.each do |transformer_class|
53
+ payload = transformer_class.new(payload).transform if transformer_class.present?
54
+ end
55
+
56
+ payload
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,10 @@
1
+ module Core
2
+ module Filtering
3
+ module Transform
4
+ module TransformationTarget
5
+ RULES = 'rules'
6
+ ADVANCED_SNIPPET = 'advanced_snippet'
7
+ end
8
+ end
9
+ end
10
+ end
@@ -11,8 +11,6 @@ require 'connectors/registry'
11
11
 
12
12
  module Core
13
13
  module Filtering
14
- DEFAULT_DOMAIN = 'DEFAULT'
15
-
16
14
  class ValidationJobRunner
17
15
  def initialize(connector_settings)
18
16
  @connector_settings = connector_settings
@@ -27,7 +25,7 @@ module Core
27
25
  validation_result = @connector_class.validate_filtering(@connector_settings.filtering[:draft])
28
26
 
29
27
  # currently only used for connectors -> DEFAULT domain can be assumed (will be changed with the integration of crawler)
30
- ElasticConnectorActions.update_filtering_validation(@connector_settings.id, { DEFAULT_DOMAIN => validation_result })
28
+ ElasticConnectorActions.update_filtering_validation(@connector_settings.id, { Core::Filtering::DEFAULT_DOMAIN => validation_result })
31
29
 
32
30
  @validation_finished = true
33
31
  rescue StandardError => e
@@ -8,10 +8,12 @@
8
8
 
9
9
  require 'core/filtering/post_process_engine'
10
10
  require 'core/filtering/post_process_result'
11
- require 'core/filtering/simple_rule'
11
+ require 'core/filtering/simple_rules/simple_rule'
12
12
  require 'core/filtering/validation_job_runner'
13
13
  require 'core/filtering/validation_status'
14
14
 
15
- module Core::Filtering
16
- DEFAULT_DOMAIN = 'DEFAULT'
15
+ module Core
16
+ module Filtering
17
+ DEFAULT_DOMAIN = 'DEFAULT'
18
+ end
17
19
  end