connectors_service 8.6.0.4.pre.20221114T233727Z → 8.6.0.4.pre.20221116T024501Z

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/config/connectors.yml +4 -4
  3. data/lib/app/app.rb +4 -0
  4. data/lib/app/dispatcher.rb +30 -17
  5. data/lib/connectors/base/advanced_snippet_against_schema_validator.rb +173 -0
  6. data/lib/connectors/base/advanced_snippet_validator.rb +34 -0
  7. data/lib/connectors/base/connector.rb +27 -5
  8. data/lib/connectors/example/connector.rb +3 -12
  9. data/lib/connectors/example/example_advanced_snippet_validator.rb +35 -0
  10. data/lib/connectors/gitlab/connector.rb +3 -12
  11. data/lib/connectors/gitlab/gitlab_advanced_snippet_validator.rb +35 -0
  12. data/lib/connectors/mongodb/connector.rb +9 -24
  13. data/lib/connectors/mongodb/mongo_advanced_snippet_against_schema_validator.rb +22 -0
  14. data/lib/connectors/mongodb/mongo_advanced_snippet_schema.rb +292 -0
  15. data/lib/connectors/sync_status.rb +6 -1
  16. data/lib/connectors/tolerable_error_helper.rb +43 -0
  17. data/lib/core/connector_job.rb +96 -23
  18. data/lib/core/connector_settings.rb +29 -6
  19. data/lib/core/elastic_connector_actions.rb +77 -55
  20. data/lib/core/filtering/validation_job_runner.rb +1 -1
  21. data/lib/core/ingestion/es_sink.rb +68 -9
  22. data/lib/core/ingestion.rb +0 -1
  23. data/lib/core/jobs/consumer.rb +114 -0
  24. data/lib/core/jobs/producer.rb +26 -0
  25. data/lib/core/single_scheduler.rb +1 -1
  26. data/lib/core/sync_job_runner.rb +20 -12
  27. data/lib/core.rb +2 -0
  28. data/lib/utility/error_monitor.rb +108 -0
  29. data/lib/utility/errors.rb +0 -12
  30. data/lib/utility/logger.rb +0 -1
  31. data/lib/utility.rb +6 -0
  32. metadata +12 -3
  33. data/lib/core/ingestion/ingester.rb +0 -90
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f69f05260d34b07ce34d569ce7c41fdd10349b33121823697ebbb6a4ebf9206
4
- data.tar.gz: a2957118c80d0e2bc9ea6a8046307485c11e4f809efb01cabbb96e341dc947c2
3
+ metadata.gz: 9a610999d9c34543392e1dd9b7b9ab136557992cc1503fa5aa5973186d17af9e
4
+ data.tar.gz: '086282a4a15ce1b168e6a0add5f78646e1fe89c336b8a257677826cce3677635'
5
5
  SHA512:
6
- metadata.gz: 63775eded9d9953b41950edd7ca86176200c4ae7510564f6f7995c336d6e78bbe40d494cb0a152a984b14b45055e7b7847a2779888d70905d4956b8c78d4bda1
7
- data.tar.gz: 52b00d122ef43fc5afa0b4cb50bbe428111e7fe2cb7cee437dd2d2b6b32516cbd01c5803b0a11609a5021e85605a2e6bd2b30973807df3cae1420864e2fcb185
6
+ metadata.gz: bf0a0a22ea96074bcbb904000ec489a591fc8491bc2d91759bc1a097c60e31c2abad7b118bb97d16bbe80c5b00dbe08f7c65653710c2d6a77d3356607d87e045
7
+ data.tar.gz: 67ff773ed2ae3f869897b5fb3a2c0dc3fc55c5922c602e032ed5bafa800043bd4b7f4af90fdd055e575ea877f3cf3b9e308d91c58bad59cd6c63dd5eb8ab98f4
@@ -1,10 +1,10 @@
1
1
  # general metadata
2
- version: 8.6.0.4-20221114T233727Z
2
+ version: 8.6.0.4-20221116T024501Z
3
3
  repository: git@github.com:elastic/ent-search-connectors.git
4
- revision: f506d5e5ebedfb0c6058d347d8ce22adc42e2cc0
4
+ revision: b3cc1332879a38930a272a63f8c6be1847578204
5
5
  elasticsearch:
6
6
  hosts: http://localhost:9200
7
- api_key: WXNYeWQ0UUJ4Y3ZQV3ctbjVibnU6REx4eE8tbFhUMU94N2JoU2hIeVFMQQ==
7
+ api_key: MDJyaGZZUUJ1ZXdOLTB1ZnQ5aXQ6a2IwQURWSjVUc1NPcjVsOFBuVDBzZw==
8
8
  retry_on_failure: 3
9
9
  request_timeout: 120
10
10
  disable_warnings: true
@@ -20,5 +20,5 @@ poll_interval: 3
20
20
  termination_timeout: 60
21
21
  heartbeat_interval: 1800
22
22
  native_mode: false
23
- connector_id: YcXyd4QBxcvPWw-n2bkA
23
+ connector_id: 0mrhfYQBuewN-0ufptgN
24
24
  service_type: mongodb
data/lib/app/app.rb CHANGED
@@ -17,6 +17,10 @@ require 'utility/logger'
17
17
  module App
18
18
  Utility::Environment.set_execution_environment(App::Config) do
19
19
  App::PreflightCheck.run!
20
+
21
+ # set exit hook
22
+ Kernel.at_exit { App::Dispatcher.shutdown! }
23
+
20
24
  App::Dispatcher.start!
21
25
  rescue App::PreflightCheck::CheckFailure => e
22
26
  Utility::Logger.error("Preflight check failed: #{e.message}")
@@ -28,6 +28,10 @@ module App
28
28
  def start!
29
29
  running!
30
30
  Utility::Logger.info("Starting connector service in #{App::Config.native_mode ? 'native' : 'non-native'} mode...")
31
+
32
+ # start sync jobs consumer
33
+ start_consumer!
34
+
31
35
  start_polling_jobs!
32
36
  end
33
37
 
@@ -37,6 +41,8 @@ module App
37
41
  scheduler.shutdown
38
42
  pool.shutdown
39
43
  pool.wait_for_termination(TERMINATION_TIMEOUT)
44
+
45
+ stop_consumer!
40
46
  end
41
47
 
42
48
  private
@@ -68,7 +74,10 @@ module App
68
74
  scheduler.when_triggered do |connector_settings, task|
69
75
  case task
70
76
  when :sync
71
- start_sync_task(connector_settings)
77
+ # update connector sync_now flag
78
+ Core::ElasticConnectorActions.update_connector_sync_now(connector_settings.id, false)
79
+
80
+ Core::Jobs::Producer.enqueue_job(job_type: :sync, connector_settings: connector_settings)
72
81
  when :heartbeat
73
82
  start_heartbeat_task(connector_settings)
74
83
  when :configuration
@@ -83,22 +92,6 @@ module App
83
92
  Utility::ExceptionTracking.log_exception(e, 'The connector service failed due to unexpected error.')
84
93
  end
85
94
 
86
- def start_sync_task(connector_settings)
87
- start_heartbeat_task(connector_settings)
88
- pool.post do
89
- Utility::Logger.info("Initiating a sync job for #{connector_settings.formatted}...")
90
- Core::ElasticConnectorActions.ensure_content_index_exists(connector_settings.index_name)
91
- job_runner = Core::SyncJobRunner.new(connector_settings)
92
- job_runner.execute
93
- rescue Core::JobAlreadyRunningError
94
- Utility::Logger.info("Sync job for #{connector_settings.formatted} is already running, skipping.")
95
- rescue Core::ConnectorVersionChangedError => e
96
- Utility::Logger.info("Could not start the job because #{connector_settings.formatted} has been updated externally. Message: #{e.message}")
97
- rescue StandardError => e
98
- Utility::ExceptionTracking.log_exception(e, "Sync job for #{connector_settings.formatted} failed due to unexpected error.")
99
- end
100
- end
101
-
102
95
  def start_heartbeat_task(connector_settings)
103
96
  pool.post do
104
97
  Utility::Logger.info("Sending heartbeat for #{connector_settings.formatted}...")
@@ -132,6 +125,26 @@ module App
132
125
  Utility::ExceptionTracking.log_exception(e, "Filter validation task for #{connector_settings.formatted} failed due to unexpected error.")
133
126
  end
134
127
  end
128
+
129
+ def start_consumer!
130
+ @consumer = Core::Jobs::Consumer.new(
131
+ poll_interval: POLL_INTERVAL,
132
+ termination_timeout: TERMINATION_TIMEOUT,
133
+ min_threads: MIN_THREADS,
134
+ max_threads: MAX_THREADS,
135
+ max_queue: MAX_QUEUE,
136
+ scheduler: scheduler
137
+ )
138
+
139
+ @consumer.subscribe!(index_name: Utility::Constants::JOB_INDEX)
140
+ end
141
+
142
+ def stop_consumer!
143
+ return if @consumer.nil?
144
+ return unless @consumer.running?
145
+
146
+ @consumer.shutdown!
147
+ end
135
148
  end
136
149
  end
137
150
  end
@@ -0,0 +1,173 @@
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'
9
+ require 'utility/logger'
10
+ require 'connectors/base/advanced_snippet_validator'
11
+ require 'core/filtering/validation_status'
12
+
13
+ module Connectors
14
+ module Base
15
+ class AdvancedSnippetAgainstSchemaValidator < Connectors::Base::AdvancedSnippetValidator
16
+
17
+ MAX_RECURSION_DEPTH = 50
18
+ ADVANCED_SNIPPET_ID = 'advanced_snippet'
19
+
20
+ def initialize(advanced_snippet, schema)
21
+ super(advanced_snippet)
22
+ @schema = schema
23
+ end
24
+
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)
34
+ # Prevent unintentional/intentional SystemStackErrors/crashes
35
+ return unexpected_error if exceeded_recursion_depth?(recursion_depth)
36
+
37
+ return valid_snippet if config_schema.nil? || config_schema.empty?
38
+
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)
41
+ schema_field_names = schema_fields.map { |field| field[:name] }
42
+
43
+ return unexpected_field(schema_field_names, snippet_field_names) if unexpected_field_present?(snippet_field_names, schema_field_names)
44
+
45
+ return fields_constraint_violation(config_schema[:fields]) if fields_constraints_violated?(config_schema, advanced_snippet)
46
+
47
+ schema_fields.each do |field|
48
+ name = field[:name]
49
+ type = field[:type]
50
+ optional = field[:optional] || false
51
+
52
+ snippet_field_value = advanced_snippet.with_indifferent_access[name]
53
+
54
+ next if optional && (snippet_field_value.nil? || !snippet_field_value.present?)
55
+
56
+ return wrong_names(snippet_field_names, name) unless snippet_field_names.include?(name)
57
+
58
+ return wrong_type(name, type, snippet_field_value) if type_error_present?(type, snippet_field_value)
59
+
60
+ if field[:fields].present?
61
+ validation_result = validate_against_schema(field, snippet_field_value, recursion_depth + 1)
62
+
63
+ return validation_result unless validation_result[:is_valid]
64
+ end
65
+ end
66
+
67
+ valid_snippet
68
+ end
69
+
70
+ def fields_constraints_violated?(config_schema, advanced_snippet)
71
+ return false unless config_schema[:fields].is_a?(Hash)
72
+
73
+ constraints = config_schema.dig(:fields, :constraints)
74
+ constraints = constraints.is_a?(Array) ? constraints : [constraints]
75
+
76
+ constraints.each do |constraint|
77
+ return true unless constraint.call(advanced_snippet)
78
+ end
79
+
80
+ false
81
+ end
82
+
83
+ def type_error_present?(schema_type, snippet_value)
84
+ return !schema_type.call(snippet_value) if schema_type.is_a?(Proc)
85
+
86
+ !snippet_value.is_a?(schema_type)
87
+ end
88
+
89
+ def exceeded_recursion_depth?(recursion_depth)
90
+ if recursion_depth >= MAX_RECURSION_DEPTH
91
+ Utility::Logger.warn("Recursion depth for filtering validation exceeded. (Max recursion depth: #{MAX_RECURSION_DEPTH})")
92
+ return true
93
+ end
94
+
95
+ false
96
+ end
97
+
98
+ def unexpected_field_present?(actual_field_names, expected_field_names)
99
+ difference = actual_field_names - expected_field_names
100
+
101
+ # we have field names, which we didn't expect
102
+ !difference.empty?
103
+ end
104
+
105
+ def valid_snippet
106
+ {
107
+ :state => Core::Filtering::ValidationStatus::VALID,
108
+ :errors => []
109
+ }
110
+ end
111
+
112
+ def unexpected_field(expected_fields, actual_fields)
113
+ {
114
+ :state => Core::Filtering::ValidationStatus::INVALID,
115
+ :errors => [
116
+ {
117
+ :ids => [ADVANCED_SNIPPET_ID],
118
+ :messages => ["Encountered unexpected fields '#{actual_fields}'. Expected: '#{expected_fields}'."]
119
+ }
120
+ ]
121
+ }
122
+ end
123
+
124
+ def wrong_type(field_name, expected_type, actual_value)
125
+ {
126
+ :state => Core::Filtering::ValidationStatus::INVALID,
127
+ :errors => [
128
+ {
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}'."]
131
+ }
132
+ ]
133
+ }
134
+ end
135
+
136
+ def wrong_names(actual_field_names, expected_field_name)
137
+ {
138
+ :state => Core::Filtering::ValidationStatus::INVALID,
139
+ :errors => [
140
+ {
141
+ :ids => [ADVANCED_SNIPPET_ID],
142
+ :messages => ["Expected field name '#{expected_field_name}', but got #{actual_field_names}."]
143
+ }
144
+ ]
145
+ }
146
+ end
147
+
148
+ def fields_constraint_violation(fields)
149
+ {
150
+ :state => Core::Filtering::ValidationStatus::INVALID,
151
+ :errors => [
152
+ {
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."]
155
+ }
156
+ ]
157
+ }
158
+ end
159
+
160
+ def unexpected_error
161
+ {
162
+ :state => Core::Filtering::ValidationStatus::INVALID,
163
+ :errors => [
164
+ {
165
+ :ids => [ADVANCED_SNIPPET_ID],
166
+ :messages => ['Unexpected error. Check logs for details.']
167
+ }
168
+ ]
169
+ }
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,34 @@
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 'utility/logger'
9
+
10
+ module Connectors
11
+ module Base
12
+ class AdvancedSnippetValidator
13
+
14
+ def initialize(advanced_snippet)
15
+ @advanced_snippet = advanced_snippet || {}
16
+ end
17
+
18
+ def is_snippet_valid?
19
+ raise 'Advanced Snippet validation not implemented'
20
+ end
21
+
22
+ private
23
+
24
+ def log_validation_result(validation_result)
25
+ Utility::Logger.info("Filtering Advanced Configuration validation result: #{validation_result[:state]}")
26
+ if validation_result[:errors].present?
27
+ validation_result[:errors].each do |error|
28
+ Utility::Logger.warn("Validation error for: '#{error[:ids]}': '#{error[:messages]}'")
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -6,12 +6,15 @@
6
6
 
7
7
  # frozen_string_literal: true
8
8
 
9
+ require 'active_support/core_ext/hash/indifferent_access'
10
+ require 'app/config'
9
11
  require 'bson'
12
+ require 'connectors/base/advanced_snippet_validator'
10
13
  require 'core/ingestion'
14
+ require 'connectors/tolerable_error_helper'
15
+ require 'core/filtering/validation_status'
11
16
  require 'utility'
12
17
  require 'utility/filtering'
13
- require 'app/config'
14
- require 'active_support/core_ext/hash/indifferent_access'
15
18
 
16
19
  module Connectors
17
20
  module Base
@@ -40,24 +43,43 @@ module Connectors
40
43
  ]
41
44
  end
42
45
 
43
- def self.validate_filtering(_filtering = {})
44
- raise 'Not implemented for this connector'
46
+ def self.advanced_snippet_validator
47
+ AdvancedSnippetValidator
48
+ end
49
+
50
+ def self.validate_filtering(filtering = {})
51
+ # nothing to validate
52
+ return { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] } unless filtering.present?
53
+
54
+ filter = Utility::Filtering.extract_filter(filtering)
55
+ advanced_snippet = filter.dig(:advanced_snippet, :value)
56
+
57
+ snippet_validator_instance = advanced_snippet_validator.new(advanced_snippet)
58
+
59
+ snippet_validator_instance.is_snippet_valid?
45
60
  end
46
61
 
47
62
  attr_reader :rules, :advanced_filter_config
48
63
 
49
64
  def initialize(configuration: {}, job_description: {})
65
+ error_monitor = Utility::ErrorMonitor.new
66
+ @tolerable_error_helper = Connectors::TolerableErrorHelper.new(error_monitor)
67
+
50
68
  @configuration = configuration.dup || {}
51
69
  @job_description = job_description&.dup || {}
52
70
 
53
71
  filtering = Utility::Filtering.extract_filter(@job_description.dig(:connector, :filtering))
54
72
 
55
73
  @rules = filtering[:rules] || []
56
- @advanced_filter_config = filtering[:advanced_snippet] || {}
74
+ @advanced_filter_config = filtering.dig(:advanced_snippet, :value) || {}
57
75
  end
58
76
 
59
77
  def yield_documents; end
60
78
 
79
+ def yield_with_handling_tolerable_errors(identifier: nil, &block)
80
+ @tolerable_error_helper.yield_single_document(identifier: identifier, &block)
81
+ end
82
+
61
83
  def do_health_check
62
84
  raise 'Not implemented for this connector'
63
85
  end
@@ -7,6 +7,7 @@
7
7
  # frozen_string_literal: true
8
8
 
9
9
  require 'connectors/base/connector'
10
+ require 'connectors/example/example_advanced_snippet_validator'
10
11
  require 'core/filtering/validation_status'
11
12
  require 'utility'
12
13
 
@@ -46,18 +47,8 @@ module Connectors
46
47
  # raise 'something went wrong'
47
48
  end
48
49
 
49
- def self.validate_filtering(filtering = {})
50
- # TODO: real filtering validation will follow later
51
- errors = [
52
- {
53
- :ids => ['missing-implementation'],
54
- :messages => ['Filtering is not implemented yet for the example connector']
55
- }
56
- ]
57
-
58
- return { :state => Core::Filtering::ValidationStatus::INVALID, :errors => errors } if filtering.present?
59
-
60
- { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
50
+ def self.advanced_snippet_validator
51
+ ExampleAdvancedSnippetValidator
61
52
  end
62
53
 
63
54
  def yield_documents
@@ -0,0 +1,35 @@
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 'connectors/base/advanced_snippet_validator'
10
+
11
+ module Connectors
12
+ module Example
13
+ class ExampleAdvancedSnippetValidator < Connectors::Base::AdvancedSnippetValidator
14
+
15
+ def is_snippet_valid?
16
+ # TODO: real filtering validation will follow later
17
+ errors = [
18
+ {
19
+ :ids => ['missing-implementation'],
20
+ :messages => ['Filtering is not implemented yet for the example connector']
21
+ }
22
+ ]
23
+
24
+ validation_result = if @advanced_snippet.present? && !@advanced_snippet.empty?
25
+ { :state => Core::Filtering::ValidationStatus::INVALID, :errors => errors }
26
+ else
27
+ { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
28
+ end
29
+ log_validation_result(validation_result)
30
+ validation_result
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -11,6 +11,7 @@ require 'connectors/base/connector'
11
11
  require 'connectors/gitlab/extractor'
12
12
  require 'connectors/gitlab/custom_client'
13
13
  require 'connectors/gitlab/adapter'
14
+ require 'connectors/gitlab/gitlab_advanced_snippet_validator'
14
15
  require 'core/ingestion'
15
16
 
16
17
  module Connectors
@@ -36,18 +37,8 @@ module Connectors
36
37
  }
37
38
  end
38
39
 
39
- def self.validate_filtering(filtering = {})
40
- # TODO: real filtering validation will follow later
41
- errors = [
42
- {
43
- :ids => ['missing-implementation'],
44
- :messages => ['Filtering is not implemented yet for the GitLab connector']
45
- }
46
- ]
47
-
48
- return { :state => Core::Filtering::ValidationStatus::INVALID, :errors => errors } if filtering.present?
49
-
50
- { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
40
+ def self.advanced_snippet_validator
41
+ GitLabAdvancedSnippetValidator
51
42
  end
52
43
 
53
44
  def initialize(configuration: {}, job_description: {})
@@ -0,0 +1,35 @@
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 'connectors/base/advanced_snippet_validator'
10
+
11
+ module Connectors
12
+ module GitLab
13
+ class GitLabAdvancedSnippetValidator < Connectors::Base::AdvancedSnippetValidator
14
+
15
+ def is_snippet_valid?
16
+ # TODO: real filtering validation will follow later
17
+ errors = [
18
+ {
19
+ :ids => ['missing-implementation'],
20
+ :messages => ['Filtering is not implemented yet for the GitLab connector']
21
+ }
22
+ ]
23
+
24
+ validation_result = if @advanced_snippet.present? && !@advanced_snippet.empty?
25
+ { :state => Core::Filtering::ValidationStatus::INVALID, :errors => errors }
26
+ else
27
+ { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
28
+ end
29
+ log_validation_result(validation_result)
30
+ validation_result
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -9,6 +9,7 @@
9
9
  require 'connectors/base/connector'
10
10
  require 'core/filtering/validation_status'
11
11
  require 'connectors/mongodb/mongo_rules_parser'
12
+ require 'connectors/mongodb/mongo_advanced_snippet_against_schema_validator'
12
13
  require 'mongo'
13
14
  require 'utility'
14
15
 
@@ -51,23 +52,8 @@ module Connectors
51
52
  }
52
53
  end
53
54
 
54
- def self.validate_filtering(filtering = {})
55
- valid_filtering = { :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
56
-
57
- return valid_filtering unless filtering.present?
58
-
59
- filter = Utility::Filtering.extract_filter(filtering)
60
-
61
- advanced_filter_config = filter[:advanced_snippet] || {}
62
- filter_keys = advanced_filter_config&.keys
63
-
64
- if !filter_keys&.empty? && (filter_keys.size != 1 || !ALLOWED_TOP_LEVEL_FILTER_KEYS.include?(filter_keys[0]&.to_s))
65
- return { :state => Core::Filtering::ValidationStatus::INVALID,
66
- :errors => [{ :ids => ['wrong-keys'],
67
- :messages => ["Only one of #{ALLOWED_TOP_LEVEL_FILTER_KEYS} is allowed in the filtering object. Keys present: '#{filter_keys}'."] }] }
68
- end
69
-
70
- valid_filtering
55
+ def self.advanced_snippet_validator
56
+ MongoAdvancedSnippetAgainstSchemaValidator
71
57
  end
72
58
 
73
59
  def initialize(configuration: {}, job_description: {})
@@ -111,13 +97,12 @@ module Connectors
111
97
  Utility::Logger.info("Requesting #{PAGE_SIZE} documents from MongoDB (Starting at #{skip})")
112
98
  view = cursor.skip(skip).limit(PAGE_SIZE)
113
99
  view.each do |document|
114
- yield serialize(document)
115
-
116
- found_in_page += 1
117
- found_overall += 1
118
-
119
- overall_limit_reached = found_overall >= overall_limit && overall_limit != Float::INFINITY
120
-
100
+ yield_with_handling_tolerable_errors do
101
+ yield serialize(document)
102
+ found_in_page += 1
103
+ found_overall += 1
104
+ overall_limit_reached = found_overall >= overall_limit && overall_limit != Float::INFINITY
105
+ end
121
106
  break if overall_limit_reached
122
107
  end
123
108
 
@@ -0,0 +1,22 @@
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 'connectors/base/advanced_snippet_against_schema_validator'
10
+ require 'connectors/mongodb/mongo_advanced_snippet_schema'
11
+
12
+ module Connectors
13
+ module MongoDB
14
+ class MongoAdvancedSnippetAgainstSchemaValidator < Connectors::Base::AdvancedSnippetAgainstSchemaValidator
15
+
16
+ def initialize(advanced_snippet, schema = Connectors::MongoDB::AdvancedSnippet::SCHEMA)
17
+ super
18
+ end
19
+
20
+ end
21
+ end
22
+ end