logstash-integration-jdbc 5.2.1 → 5.2.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5826d365fd1f0f71ef3562e40e51d68b9bf76585bbd536eb5868a56c5bb6aacb
4
- data.tar.gz: 5ae08858db8043a0840d7a8578eae295e99b6a1da4ca3ec9239ee0730298188e
3
+ metadata.gz: ad77fc92ab07e1da7e4c6285075b6583f9f293c073199b614e3852cd22bbc6a9
4
+ data.tar.gz: 9e7b2c0f0c16930903bdee1f22b2651db7cf9f80d01a12f212b7a40155d4ebea
5
5
  SHA512:
6
- metadata.gz: 685637b889432ff5378e6c9873a90b183a90337a011d9719c17b6928721fbef01e393b111f35d2d4d19e7a8bc62eeffd98d93964e46494f486b93f7a9b45bff3
7
- data.tar.gz: 30f804b0e420b7485da98805e80902ae2d8b33417256938706ba79f0f20fe62d8da2bec9a6c716e50a30f3455f0cb86f6757eef9811e631685f3e620c8c6a604
6
+ metadata.gz: 2928a01bbe1ef418f36d6ddc7847416fc6d43278b20242926037bef02e8a429ba1d4587f1bd88f8d52de2ec1fef26e749aeb358de82a8bf69c36e5c3c9d42f8e
7
+ data.tar.gz: 8aae596826ec1d9155e0f8bdfad9a882e92fa2be610f89d7c67a7b3f44f0e6937bcbafd78900457d92b20a5a28188163f7b4f25040d8deb229f505ab6faf2c22
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 5.2.4
2
+ - Fix: compatibility with all (>= 3.0) rufus-scheduler versions [#97](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/97)
3
+
4
+ ## 5.2.3
5
+ - Performance: avoid contention on scheduler execution [#103](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/103)
6
+
7
+ ## 5.2.2
8
+ - Feat: name scheduler threads + redirect error logging [#102](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/102)
9
+
1
10
  ## 5.2.1
2
11
  - Refactor: isolate paginated normal statement algorithm in a separate handler [#101](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/101)
3
12
 
data/Gemfile CHANGED
@@ -9,3 +9,5 @@ if Dir.exist?(logstash_path) && use_logstash_source
9
9
  gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
10
10
  gem 'logstash-core-plugin-api', :path => "#{logstash_path}/logstash-core-plugin-api"
11
11
  end
12
+
13
+ gem 'rufus-scheduler', ENV['RUFUS_SCHEDULER_VERSION'] if ENV['RUFUS_SCHEDULER_VERSION']
@@ -4,60 +4,26 @@ require "rufus/scheduler"
4
4
 
5
5
  module LogStash module Filters module Jdbc
6
6
  class LoaderSchedule < Validatable
7
- attr_reader :schedule_frequency, :loader_schedule
8
-
9
- def to_log_string
10
- message = ""
11
- message.concat "these months in the year [#{@cronline.months.to_a.join(", ")}];" unless @cronline.months.nil?
12
- message.concat "these days in the month [#{@cronline.days.to_a.join(", ")}];" unless @cronline.days.nil?
13
- message.concat "these hours in the day [#{@cronline.hours.to_a.join(", ")}];" unless @cronline.hours.nil?
14
- message.concat "these minutes in the hour [#{@cronline.minutes.to_a.join(", ")}];" unless @cronline.minutes.nil?
15
- message.concat "these seconds in the minute [#{@cronline.seconds.to_a.join(", ")}]" unless @cronline.seconds.nil?
16
- if !message.empty?
17
- message.prepend "Scheduled for: "
18
- end
19
- message
20
- end
7
+ attr_reader :loader_schedule
21
8
 
22
9
  private
23
10
 
24
- def post_initialize
25
- if valid?
26
- # From the Rufus::Scheduler docs:
27
- # By default, rufus-scheduler sleeps 0.300 second between every step.
28
- # At each step it checks for jobs to trigger and so on.
29
- # set the frequency to 2.5 seconds if we are not reloading in the seconds timeframe
30
- # rufus scheduler thread should respond to stop quickly enough.
31
- if only_seconds_set?
32
- @schedule_frequency = 0.3
33
- else
34
- @schedule_frequency = 2.5
35
- end
36
- end
37
- end
38
-
39
-
40
- def only_seconds_set?
41
- @cronline.seconds &&
42
- @cronline.minutes.nil? &&
43
- @cronline.hours.nil? &&
44
- @cronline.days.nil? &&
45
- @cronline.months.nil?
46
- end
47
-
11
+ # @overload
48
12
  def parse_options
49
13
  @loader_schedule = @options
50
14
 
51
- unless @loader_schedule.is_a?(String)
15
+ if @loader_schedule.is_a?(String)
16
+ begin
17
+ # Rufus::Scheduler 3.0 - 3.6 methods signature: parse_cron(o, opts)
18
+ # since Rufus::Scheduler 3.7 methods signature: parse_cron(o, opts={})
19
+ @cronline = Rufus::Scheduler.parse_cron(@loader_schedule, {})
20
+ rescue => e
21
+ @option_errors << "The loader_schedule option is invalid: #{e.message}"
22
+ end
23
+ else
52
24
  @option_errors << "The loader_schedule option must be a string"
53
25
  end
54
26
 
55
- begin
56
- @cronline = Rufus::Scheduler::CronLine.new(@loader_schedule)
57
- rescue => e
58
- @option_errors << "The loader_schedule option is invalid: #{e.message}"
59
- end
60
-
61
27
  @valid = @option_errors.empty?
62
28
  end
63
29
  end
@@ -3,8 +3,6 @@ require_relative "single_load_runner"
3
3
 
4
4
  module LogStash module Filters module Jdbc
5
5
  class RepeatingLoadRunner < SingleLoadRunner
6
- # info - attr_reader :local, :loaders, :preloaders
7
-
8
6
  def repeated_load
9
7
  local.repopulate_all(loaders)
10
8
  @reload_counter.increment
@@ -26,10 +26,6 @@ module LogStash module Filters module Jdbc
26
26
  def repeated_load
27
27
  end
28
28
 
29
- def call
30
- repeated_load
31
- end
32
-
33
29
  def reload_count
34
30
  @reload_counter.value
35
31
  end
@@ -3,6 +3,7 @@ require "logstash-integration-jdbc_jars"
3
3
  require "logstash/filters/base"
4
4
  require "logstash/namespace"
5
5
  require "logstash/plugin_mixins/ecs_compatibility_support"
6
+ require "logstash/plugin_mixins/jdbc/scheduler"
6
7
  require_relative "jdbc/loader"
7
8
  require_relative "jdbc/loader_schedule"
8
9
  require_relative "jdbc/repeating_load_runner"
@@ -191,17 +192,15 @@ module LogStash module Filters class JdbcStatic < LogStash::Filters::Base
191
192
  @processor = Jdbc::LookupProcessor.new(@local_lookups, global_lookup_options)
192
193
  runner_args.unshift(@processor.local)
193
194
  if @loader_schedule
194
- args = []
195
195
  @loader_runner = Jdbc::RepeatingLoadRunner.new(*runner_args)
196
196
  @loader_runner.initial_load
197
- cronline = Jdbc::LoaderSchedule.new(@loader_schedule)
198
- cronline.to_log_string.tap do |msg|
199
- logger.info("Scheduler operations: #{msg}") unless msg.empty?
197
+ @scheduler = LogStash::PluginMixins::Jdbc::Scheduler.
198
+ start_cron_scheduler(@loader_schedule, thread_name: "[#{id}]-jdbc_static__scheduler") { @loader_runner.repeated_load }
199
+ cron_job = @scheduler.cron_jobs.first
200
+ if cron_job
201
+ frequency = cron_job.respond_to?(:rough_frequency) ? cron_job.rough_frequency : cron_job.frequency
202
+ logger.info("Loaders will execute every #{frequency} seconds", loader_schedule: @loader_schedule)
200
203
  end
201
- logger.info("Scheduler scan for work frequency is: #{cronline.schedule_frequency}")
202
- rufus_args = {:max_work_threads => 1, :frequency => cronline.schedule_frequency}
203
- @scheduler = Rufus::Scheduler.new(rufus_args)
204
- @scheduler.cron(cronline.loader_schedule, @loader_runner)
205
204
  else
206
205
  @loader_runner = Jdbc::SingleLoadRunner.new(*runner_args)
207
206
  @loader_runner.initial_load
@@ -3,6 +3,7 @@ require "logstash/inputs/base"
3
3
  require "logstash/namespace"
4
4
  require "logstash/plugin_mixins/jdbc/common"
5
5
  require "logstash/plugin_mixins/jdbc/jdbc"
6
+ require "logstash/plugin_mixins/jdbc/scheduler"
6
7
  require "logstash/plugin_mixins/ecs_compatibility_support"
7
8
  require "logstash/plugin_mixins/ecs_compatibility_support/target_check"
8
9
  require "logstash/plugin_mixins/validator_support/field_reference_validation_adapter"
@@ -293,11 +294,9 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
293
294
  def run(queue)
294
295
  load_driver
295
296
  if @schedule
296
- @scheduler = Rufus::Scheduler.new(:max_work_threads => 1)
297
- @scheduler.cron @schedule do
298
- execute_query(queue)
299
- end
300
-
297
+ # input thread (Java) name example "[my-oracle]<jdbc"
298
+ @scheduler = LogStash::PluginMixins::Jdbc::Scheduler.
299
+ start_cron_scheduler(@schedule, thread_name: "[#{id}]<jdbc__scheduler") { execute_query(queue) }
301
300
  @scheduler.join
302
301
  else
303
302
  execute_query(queue)
@@ -220,7 +220,8 @@ module LogStash module PluginMixins module Jdbc
220
220
  end
221
221
  success = true
222
222
  rescue Sequel::DatabaseConnectionError, Sequel::DatabaseError, Java::JavaSql::SQLException => e
223
- details = { :exception => e.message }
223
+ details = { exception: e.class, message: e.message }
224
+ details[:cause] = e.cause.inspect if e.cause
224
225
  details[:backtrace] = e.backtrace if @logger.debug?
225
226
  @logger.warn("Exception when executing JDBC query", details)
226
227
  else
@@ -0,0 +1,175 @@
1
+ require 'rufus/scheduler'
2
+
3
+ require 'logstash/util/loggable'
4
+
5
+ module LogStash module PluginMixins module Jdbc
6
+ class Scheduler < Rufus::Scheduler
7
+
8
+ include LogStash::Util::Loggable
9
+
10
+ # Rufus::Scheduler >= 3.4 moved the Time impl into a gem EoTime = ::EtOrbi::EoTime`
11
+ # Rufus::Scheduler 3.1 - 3.3 using it's own Time impl `Rufus::Scheduler::ZoTime`
12
+ TimeImpl = defined?(Rufus::Scheduler::EoTime) ? Rufus::Scheduler::EoTime :
13
+ (defined?(Rufus::Scheduler::ZoTime) ? Rufus::Scheduler::ZoTime : ::Time)
14
+
15
+ # @param cron [String] cron-line
16
+ # @param opts [Hash] scheduler options
17
+ # @return scheduler instance
18
+ def self.start_cron_scheduler(cron, opts = {}, &block)
19
+ unless block_given?
20
+ raise ArgumentError, 'missing (cron scheduler) block - worker task to execute'
21
+ end
22
+ scheduler = new_scheduler(opts)
23
+ scheduler.schedule_cron(cron, &block)
24
+ scheduler
25
+ end
26
+
27
+ # @param opts [Hash] scheduler options
28
+ # @return scheduler instance
29
+ def self.new_scheduler(opts)
30
+ unless opts.key?(:thread_name)
31
+ raise ArgumentError, 'thread_name: option is required to be able to distinguish multiple scheduler threads'
32
+ end
33
+ opts[:max_work_threads] ||= 1
34
+ # amount the scheduler thread sleeps between checking whether jobs
35
+ # should trigger, default is 0.3 which is a bit too often ...
36
+ # in theory the cron expression '* * * * * *' supports running jobs
37
+ # every second but this is very rare, we could potentially go higher
38
+ opts[:frequency] ||= 1.0
39
+
40
+ new(opts)
41
+ end
42
+
43
+ # @overload
44
+ def timeout_jobs
45
+ # Rufus relies on `Thread.list` which is a blocking operation and with many schedulers
46
+ # (and threads) within LS will have a negative impact on performance as scheduler
47
+ # threads will end up waiting to obtain the `Thread.list` lock.
48
+ #
49
+ # However, this isn't necessary we can easily detect whether there are any jobs
50
+ # that might need to timeout: only when `@opts[:timeout]` is set causes worker thread(s)
51
+ # to have a `Thread.current[:rufus_scheduler_timeout]` that is not nil
52
+ return unless @opts[:timeout]
53
+ super
54
+ end
55
+
56
+ # @overload
57
+ def work_threads(query = :all)
58
+ if query == :__all_no_cache__ # special case from JobDecorator#start_work_thread
59
+ @_work_threads = nil # when a new worker thread is being added reset
60
+ return super(:all)
61
+ end
62
+
63
+ # Gets executed every time a job is triggered, we're going to cache the
64
+ # worker threads for this scheduler (to avoid `Thread.list`) - they only
65
+ # change when a new thread is being started from #start_work_thread ...
66
+ work_threads = @_work_threads
67
+ if work_threads.nil?
68
+ work_threads = threads.select { |t| t[:rufus_scheduler_work_thread] }
69
+ @_work_threads = work_threads
70
+ end
71
+
72
+ case query
73
+ when :active then work_threads.select { |t| t[:rufus_scheduler_job] }
74
+ when :vacant then work_threads.reject { |t| t[:rufus_scheduler_job] }
75
+ else work_threads
76
+ end
77
+ end
78
+
79
+ # @overload
80
+ def on_error(job, err)
81
+ details = { exception: err.class, message: err.message, backtrace: err.backtrace }
82
+ details[:cause] = err.cause if err.cause
83
+
84
+ details[:now] = debug_format_time(TimeImpl.now)
85
+ details[:last_time] = (debug_format_time(job.last_time) rescue nil)
86
+ details[:next_time] = (debug_format_time(job.next_time) rescue nil)
87
+ details[:job] = job
88
+
89
+ details[:opts] = @opts
90
+ details[:started_at] = started_at
91
+ details[:thread] = thread.inspect
92
+ details[:jobs_size] = @jobs.size
93
+ details[:work_threads_size] = work_threads.size
94
+ details[:work_queue_size] = work_queue.size
95
+
96
+ logger.error("Scheduler intercepted an error:", details)
97
+
98
+ rescue => e
99
+ logger.error("Scheduler failed in #on_error #{e.inspect}")
100
+ end
101
+
102
+ def debug_format_time(time)
103
+ # EtOrbi::EoTime used by (newer) Rufus::Scheduler has to_debug_s https://git.io/JyiPj
104
+ time.respond_to?(:to_debug_s) ? time.to_debug_s : time.strftime("%Y-%m-%dT%H:%M:%S.%L")
105
+ end
106
+ private :debug_format_time
107
+
108
+ # @private helper used by JobDecorator
109
+ def work_thread_name_prefix
110
+ ( @opts[:thread_name] || "#{@thread_key}_scheduler" ) + '_worker-'
111
+ end
112
+
113
+ protected
114
+
115
+ # @overload
116
+ def start
117
+ ret = super() # @thread[:name] = @opts[:thread_name] || "#{@thread_key}_scheduler"
118
+
119
+ # at least set thread.name for easier thread dump analysis
120
+ if @thread.is_a?(Thread) && @thread.respond_to?(:name=)
121
+ @thread.name = @thread[:name] if @thread[:name]
122
+ end
123
+
124
+ ret
125
+ end
126
+
127
+ # @overload
128
+ def do_schedule(job_type, t, callable, opts, return_job_instance, block)
129
+ job_or_id = super
130
+
131
+ job_or_id.extend JobDecorator if return_job_instance
132
+
133
+ job_or_id
134
+ end
135
+
136
+ module JobDecorator
137
+
138
+ def start_work_thread
139
+ prev_thread_count = @scheduler.work_threads.size
140
+
141
+ ret = super() # does not return Thread instance in 3.0
142
+
143
+ work_threads = @scheduler.work_threads(:__all_no_cache__)
144
+ while prev_thread_count == work_threads.size # very unlikely
145
+ Thread.pass
146
+ work_threads = @scheduler.work_threads(:__all_no_cache__)
147
+ end
148
+
149
+ work_thread_name_prefix = @scheduler.work_thread_name_prefix
150
+
151
+ work_threads.sort! do |t1, t2|
152
+ if t1[:name].nil?
153
+ t2[:name].nil? ? 0 : +1 # nils at the end
154
+ elsif t2[:name].nil?
155
+ t1[:name].nil? ? 0 : -1
156
+ else
157
+ t1[:name] <=> t2[:name]
158
+ end
159
+ end
160
+
161
+ work_threads.each_with_index do |thread, i|
162
+ unless thread[:name]
163
+ thread[:name] = "#{work_thread_name_prefix}#{sprintf('%02i', i)}"
164
+ thread.name = thread[:name] if thread.respond_to?(:name=)
165
+ # e.g. "[oracle]<jdbc_scheduler_worker-00"
166
+ end
167
+ end
168
+
169
+ ret
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+ end end end
@@ -6,9 +6,6 @@ module LogStash module PluginMixins module Jdbc
6
6
 
7
7
  def self.build_last_value_tracker(plugin)
8
8
  handler = plugin.record_last_run ? FileHandler.new(plugin.last_run_metadata_path) : NullFileHandler.new(plugin.last_run_metadata_path)
9
- if plugin.record_last_run
10
- handler = FileHandler.new(plugin.last_run_metadata_path)
11
- end
12
9
  if plugin.clean_run
13
10
  handler.clean
14
11
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-jdbc'
3
- s.version = '5.2.1'
3
+ s.version = '5.2.4'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "Integration with JDBC - input and filter plugins"
6
6
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -34,8 +34,9 @@ Gem::Specification.new do |s|
34
34
 
35
35
  s.add_runtime_dependency 'tzinfo'
36
36
  s.add_runtime_dependency 'tzinfo-data'
37
- # 3.5 limitation is required for jdbc-static loading schedule
38
- s.add_runtime_dependency 'rufus-scheduler', '< 3.5'
37
+ # plugin maintains compatibility with < 3.5 (3.0.9)
38
+ # but works with newer rufus-scheduler >= 3.5 as well
39
+ s.add_runtime_dependency 'rufus-scheduler'
39
40
  s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.3'
40
41
  s.add_runtime_dependency "logstash-mixin-validator_support", '~> 1.0'
41
42
  s.add_runtime_dependency "logstash-mixin-event_support", '~> 1.0'
@@ -17,7 +17,7 @@ module LogStash module Filters module Jdbc
17
17
  expect(local_db).to receive(:populate_all).once.with(loaders)
18
18
  expect(local_db).to receive(:repopulate_all).once.with(loaders)
19
19
  runner.initial_load
20
- subject.call
20
+ subject.repeated_load
21
21
  end
22
22
  end
23
23
  end
@@ -70,7 +70,7 @@ describe LogStash::Inputs::Jdbc, :integration => true do
70
70
  plugin.register
71
71
  expect( plugin ).to receive(:log_java_exception)
72
72
  expect(plugin.logger).to receive(:warn).once.with("Exception when executing JDBC query",
73
- hash_including(:exception => instance_of(String)))
73
+ hash_including(:message => instance_of(String)))
74
74
  q = Queue.new
75
75
  expect{ plugin.run(q) }.not_to raise_error
76
76
  end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/plugin_mixins/jdbc/scheduler"
4
+
5
+ describe LogStash::PluginMixins::Jdbc::Scheduler do
6
+
7
+ let(:thread_name) { '[test]<jdbc_scheduler' }
8
+
9
+ let(:opts) do
10
+ { :max_work_threads => 2, :thread_name => thread_name }
11
+ end
12
+
13
+ subject(:scheduler) { LogStash::PluginMixins::Jdbc::Scheduler.new(opts) }
14
+
15
+ after { scheduler.stop(:wait) }
16
+
17
+ it "sets scheduler thread name" do
18
+ expect( scheduler.thread.name ).to include thread_name
19
+ end
20
+
21
+ context 'cron schedule' do
22
+
23
+ before do
24
+ scheduler.schedule_cron('* * * * * *') { sleep 1.25 } # every second
25
+ end
26
+
27
+ it "sets worker thread names" do
28
+ sleep 3.0
29
+ threads = scheduler.work_threads
30
+ threads.sort! { |t1, t2| (t1.name || '') <=> (t2.name || '') }
31
+
32
+ expect( threads.size ).to eql 2
33
+ expect( threads.first.name ).to eql "#{thread_name}_worker-00"
34
+ expect( threads.last.name ).to eql "#{thread_name}_worker-01"
35
+ end
36
+
37
+ end
38
+
39
+ context 'every 1s' do
40
+
41
+ before do
42
+ scheduler.schedule_in('1s') { raise 'TEST' } # every second
43
+ end
44
+
45
+ it "logs errors handled" do
46
+ expect( scheduler.logger ).to receive(:error).with /Scheduler intercepted an error/, hash_including(:message => 'TEST')
47
+ sleep 1.5
48
+ end
49
+
50
+ end
51
+
52
+ context 'work threads' do
53
+
54
+ let(:opts) { super().merge :max_work_threads => 3 }
55
+
56
+ let(:counter) { java.util.concurrent.atomic.AtomicLong.new(0) }
57
+
58
+ before do
59
+ scheduler.schedule_cron('* * * * * *') { counter.increment_and_get; sleep 3.25 } # every second
60
+ end
61
+
62
+ it "are working" do
63
+ sleep(0.05) while counter.get == 0
64
+ expect( scheduler.work_threads.size ).to eql 1
65
+ sleep(0.05) while counter.get == 1
66
+ expect( scheduler.work_threads.size ).to eql 2
67
+ sleep(0.05) while counter.get == 2
68
+ expect( scheduler.work_threads.size ).to eql 3
69
+
70
+ sleep 1.25
71
+ expect( scheduler.work_threads.size ).to eql 3
72
+ sleep 1.25
73
+ expect( scheduler.work_threads.size ).to eql 3
74
+ end
75
+
76
+ end
77
+
78
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-integration-jdbc
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.1
4
+ version: 5.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-22 00:00:00.000000000 Z
11
+ date: 2022-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -131,17 +131,17 @@ dependencies:
131
131
  - !ruby/object:Gem::Dependency
132
132
  requirement: !ruby/object:Gem::Requirement
133
133
  requirements:
134
- - - "<"
134
+ - - ">="
135
135
  - !ruby/object:Gem::Version
136
- version: '3.5'
136
+ version: '0'
137
137
  name: rufus-scheduler
138
138
  prerelease: false
139
139
  type: :runtime
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
- - - "<"
142
+ - - ">="
143
143
  - !ruby/object:Gem::Version
144
- version: '3.5'
144
+ version: '0'
145
145
  - !ruby/object:Gem::Dependency
146
146
  requirement: !ruby/object:Gem::Requirement
147
147
  requirements:
@@ -278,6 +278,7 @@ files:
278
278
  - lib/logstash/plugin_mixins/jdbc/checked_count_logger.rb
279
279
  - lib/logstash/plugin_mixins/jdbc/common.rb
280
280
  - lib/logstash/plugin_mixins/jdbc/jdbc.rb
281
+ - lib/logstash/plugin_mixins/jdbc/scheduler.rb
281
282
  - lib/logstash/plugin_mixins/jdbc/statement_handler.rb
282
283
  - lib/logstash/plugin_mixins/jdbc/value_tracking.rb
283
284
  - lib/logstash/plugin_mixins/jdbc_streaming.rb
@@ -306,6 +307,7 @@ files:
306
307
  - spec/helpers/derbyrun.jar
307
308
  - spec/inputs/integration/integ_spec.rb
308
309
  - spec/inputs/jdbc_spec.rb
310
+ - spec/plugin_mixins/jdbc/scheduler_spec.rb
309
311
  - spec/plugin_mixins/jdbc_streaming/parameter_handler_spec.rb
310
312
  - vendor/jar-dependencies/org/apache/derby/derby/10.14.1.0/derby-10.14.1.0.jar
311
313
  - vendor/jar-dependencies/org/apache/derby/derbyclient/10.14.1.0/derbyclient-10.14.1.0.jar
@@ -358,4 +360,5 @@ test_files:
358
360
  - spec/helpers/derbyrun.jar
359
361
  - spec/inputs/integration/integ_spec.rb
360
362
  - spec/inputs/jdbc_spec.rb
363
+ - spec/plugin_mixins/jdbc/scheduler_spec.rb
361
364
  - spec/plugin_mixins/jdbc_streaming/parameter_handler_spec.rb