logstash-integration-jdbc 5.1.6 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef9180da50049c113170083c54826d75aadc91883fdca644bd82b5802ccd7234
4
- data.tar.gz: 55b6adf668a1aac55c7a5883ae02de29431bcdf1e58d2177ab6004524bd99780
3
+ metadata.gz: a41fe10947372ac69f9db7a66dd1c285000f27bba0cb77ef7ec62629821fa5b3
4
+ data.tar.gz: 74b411ebe9f448259da6751def456535bf6819f84c80027a629354140fc5c779
5
5
  SHA512:
6
- metadata.gz: 22e48f5ac21bde7821142cc77accd458dd695a8895941bed7d7a495459d06663c2166c94c91f9592f1621f119a9c796c186401542a8085f01abd6544b3345376
7
- data.tar.gz: 3f0a613c6bd1d4a9c8b272ec6b344bc0f791f5a137f25adbee547fbece9d7a5a01028f125641255186266d47714bb47e499325c21700d865c4cc9bf22dd529f2
6
+ metadata.gz: '029c86dfb0a4099979c77443c79edc7ebfb1cc3572d54c43c9864642aa018892cede9e749685846ad3451defabb1cea1cc770f3c4062afaa06690a67c0a1d498'
7
+ data.tar.gz: 3c60fa57ef6c77bee21be8c3eac9b12c5f32af0b9fa7b4874dd8503ce6926b87ff139a2293a2276156df0ae6ec20ce238ed467ee803bc510452ab2d732d090a7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 5.2.0
2
+ - Added `jdbc_paging_mode` option to choose if use `explicit` pagination in statements and avoid the initial count
3
+ query or use `auto` to delegate to the underlying library [#95](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/95)
4
+
5
+ ## 5.1.10
6
+ - Refactor: to explicit Java (driver) class name loading [#96](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/96),
7
+ the change is expected to provide a more robust fix for the driver loading issue [#83](https://github.com/logstash-plugins/logstash-integration-jdbc/issues/83).
8
+
9
+ NOTE: a fatal driver error will no longer keep reloading the pipeline and now leads to a system exit.
10
+
11
+ - Fix: regression due returning the Java driver class [#98](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/98)
12
+
13
+ ## 5.1.9 (yanked)
14
+ - Refactor: to explicit Java (driver) class name loading [#96](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/96),
15
+ the change is expected to provide a more robust fix for the driver loading issue [#83](https://github.com/logstash-plugins/logstash-integration-jdbc/issues/83).
16
+
17
+ ## 5.1.8
18
+ - Fix the blocking pipeline reload and shutdown when connectivity issues happen [#85](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/85)
19
+
20
+ ## 5.1.7
21
+ - Normalize jdbc_driver_class loading to support any top-level java packages [#86](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/86)
22
+
1
23
  ## 5.1.6
2
24
  - Fix, serialize the JDBC driver loading steps to avoid concurrency issues [#84](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/84)
3
25
 
@@ -129,6 +129,9 @@ Here is the list:
129
129
  |sql_last_value | The value used to calculate which rows to query. Before any query is run,
130
130
  this is set to Thursday, 1 January 1970, or 0 if `use_column_value` is true and
131
131
  `tracking_column` is set. It is updated accordingly after subsequent queries are run.
132
+ |offset, size| Values used with manual paging mode to explicitly implement the paging.
133
+ Supported only if <<plugins-{type}s-{plugin}-jdbc_paging_enabled>> is enabled and
134
+ <<plugins-{type}s-{plugin}-jdbc_paging_mode>> has the `explicit` value.
132
135
  |==========================================================
133
136
 
134
137
  Example:
@@ -153,7 +156,7 @@ NOTE: Not all JDBC accessible technologies will support prepared statements.
153
156
  With the introduction of Prepared Statement support comes a different code execution path and some new settings. Most of the existing settings are still useful but there are several new settings for Prepared Statements to read up on.
154
157
  Use the boolean setting `use_prepared_statements` to enable this execution mode. Use the `prepared_statement_name` setting to specify a name for the Prepared Statement, this identifies the prepared statement locally and remotely and it should be unique in your config and on the database. Use the `prepared_statement_bind_values` array setting to specify the bind values, use the exact string `:sql_last_value` (multiple times if necessary) for the predefined parameter mentioned before. The `statement` (or `statement_path`) setting still holds the SQL statement but to use bind variables you must use the `?` character as a placeholder in the exact order found in the `prepared_statement_bind_values` array.
155
158
 
156
- NOTE: Building count queries around a prepared statement is not supported at this time and because jdbc paging uses count queries under the hood, jdbc paging is not supported with prepared statements at this time either. Therefore, `jdbc_paging_enabled`, `jdbc_page_size` settings are ignored when using prepared statements.
159
+ NOTE: Building count queries around a prepared statement is not supported at this time. Because jdbc paging uses count queries when `jdbc_paging_mode` has value `auto`,jdbc paging is not supported with prepared statements at this time either. Therefore, `jdbc_paging_enabled`, `jdbc_page_size` settings are ignored when using prepared statements.
157
160
 
158
161
  Example:
159
162
  [source,ruby]
@@ -193,6 +196,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
193
196
  | <<plugins-{type}s-{plugin}-jdbc_fetch_size>> |<<number,number>>|No
194
197
  | <<plugins-{type}s-{plugin}-jdbc_page_size>> |<<number,number>>|No
195
198
  | <<plugins-{type}s-{plugin}-jdbc_paging_enabled>> |<<boolean,boolean>>|No
199
+ | <<plugins-{type}s-{plugin}-jdbc_paging_mode>> |<<string,string>>, one of `["auto", "explicit"]`|No
196
200
  | <<plugins-{type}s-{plugin}-jdbc_password>> |<<password,password>>|No
197
201
  | <<plugins-{type}s-{plugin}-jdbc_password_filepath>> |a valid filesystem path|No
198
202
  | <<plugins-{type}s-{plugin}-jdbc_pool_timeout>> |<<number,number>>|No
@@ -373,6 +377,52 @@ result-set. The limit size is set with `jdbc_page_size`.
373
377
 
374
378
  Be aware that ordering is not guaranteed between queries.
375
379
 
380
+ [id="plugins-{type}s-{plugin}-jdbc_paging_mode"]
381
+ ===== `jdbc_paging_mode`
382
+
383
+ * Value can be any of: `auto`, `explicit`
384
+ * Default value is `"auto"`
385
+
386
+ Whether to use `explicit` or `auto` mode during the JDBC paging
387
+
388
+ If `auto`, your statement will be automatically surrounded by a count query and subsequent multiple paged queries (with `LIMIT` statement, etc.).
389
+
390
+ If `explicit`, multiple queries (without a count query ahead) will be performed with your statement, until no more rows are retrieved.
391
+ You have to write your own paging conditions in your statement configuration.
392
+ The `offset` and `size` parameters can be used in your statement (`size` equal to `jdbc_page_size`, and `offset` incremented by `size` for each query).
393
+ When the number of rows returned by the query is not equal to `size`, SQL paging will be ended.
394
+ Example:
395
+
396
+ [source, ruby]
397
+ ------------------------------------------------------
398
+ input {
399
+ jdbc {
400
+ statement => "SELECT id, mycolumn1, mycolumn2 FROM my_table WHERE id > :sql_last_value LIMIT :size OFFSET :offset",
401
+ jdbc_paging_enabled => true,
402
+ jdbc_paging_mode => "explicit",
403
+ jdbc_page_size => 100000
404
+ }
405
+ }
406
+ ------------------------------------------------------
407
+
408
+ [source, ruby]
409
+ ------------------------------------------------------
410
+ input {
411
+ jdbc {
412
+ statement => "CALL fetch_my_data(:sql_last_value, :offset, :size)",
413
+ jdbc_paging_enabled => true,
414
+ jdbc_paging_mode => "explicit",
415
+ jdbc_page_size => 100000
416
+ }
417
+ }
418
+ ------------------------------------------------------
419
+
420
+ This mode can be considered in the following situations:
421
+
422
+ . Performance issues encountered in default paging mode.
423
+ . Your SQL statement is complex, so simply surrounding it with paging statements is not what you want.
424
+ . Your statement is a stored procedure, and the actual paging statement is inside it.
425
+
376
426
  [id="plugins-{type}s-{plugin}-jdbc_password"]
377
427
  ===== `jdbc_password`
378
428
 
@@ -1,9 +1,12 @@
1
+ require 'jruby'
1
2
 
2
3
  module LogStash module PluginMixins module Jdbc
3
4
  module Common
4
5
 
5
6
  private
6
7
 
8
+ # NOTE: using the JRuby mechanism to load classes (through JavaSupport)
9
+ # makes the lock redundant although it does not hurt to have it around.
7
10
  DRIVERS_LOADING_LOCK = java.util.concurrent.locks.ReentrantLock.new()
8
11
 
9
12
  def complete_sequel_opts(defaults = {})
@@ -30,16 +33,16 @@ module LogStash module PluginMixins module Jdbc
30
33
  begin
31
34
  load_driver_jars
32
35
  begin
33
- @driver_impl = Sequel::JDBC.load_driver(@jdbc_driver_class)
34
- rescue Sequel::AdapterNotFound => e # Sequel::AdapterNotFound, "#{@jdbc_driver_class} not loaded"
35
- # fix this !!!
36
+ @driver_impl = load_jdbc_driver_class
37
+ rescue => e # catch java.lang.ClassNotFoundException, potential errors
38
+ # (e.g. ExceptionInInitializerError or LinkageError) won't get caught
36
39
  message = if jdbc_driver_library_set?
37
40
  "Are you sure you've included the correct jdbc driver in :jdbc_driver_library?"
38
41
  else
39
42
  ":jdbc_driver_library is not set, are you sure you included " +
40
43
  "the proper driver client libraries in your classpath?"
41
44
  end
42
- raise LogStash::PluginLoadingError, "#{e}. #{message} #{e.backtrace}"
45
+ raise LogStash::PluginLoadingError, "#{e.inspect}. #{message}"
43
46
  end
44
47
  ensure
45
48
  DRIVERS_LOADING_LOCK.unlock()
@@ -71,5 +74,16 @@ module LogStash module PluginMixins module Jdbc
71
74
  !@jdbc_driver_library.nil? && !@jdbc_driver_library.empty?
72
75
  end
73
76
 
77
+ def load_jdbc_driver_class
78
+ # sub a potential: 'Java::org::my.Driver' to 'org.my.Driver'
79
+ klass = @jdbc_driver_class.gsub('::', '.').sub(/^Java\./, '')
80
+ # NOTE: JRuby's Java::JavaClass.for_name which considers the custom class-loader(s)
81
+ # in 9.3 the API changed and thus to avoid surprises we go down to the Java API :
82
+ klass = JRuby.runtime.getJavaSupport.loadJavaClass(klass) # throws ClassNotFoundException
83
+ # unfortunately we can not simply return the wrapped java.lang.Class instance as
84
+ # Sequel assumes to be able to do a `driver_class.new` which only works on the proxy,
85
+ org.jruby.javasupport.Java.getProxyClass(JRuby.runtime, klass)
86
+ end
87
+
74
88
  end
75
89
  end end end
@@ -55,6 +55,9 @@ module LogStash module PluginMixins module Jdbc
55
55
  # Be aware that ordering is not guaranteed between queries.
56
56
  config :jdbc_paging_enabled, :validate => :boolean, :default => false
57
57
 
58
+ # Which pagination mode to use, automatic pagination or explicitly defined in the query.
59
+ config :jdbc_paging_mode, :validate => [ "auto", "explicit" ], :default => "auto"
60
+
58
61
  # JDBC page size
59
62
  config :jdbc_page_size, :validate => :number, :default => 100000
60
63
 
@@ -168,8 +171,6 @@ module LogStash module PluginMixins module Jdbc
168
171
  @logger.warn("Failed test_connection with java.sql.SQLException.", :exception => e)
169
172
  rescue Sequel::DatabaseConnectionError => e
170
173
  @logger.warn("Failed test_connection.", :exception => e)
171
- close_jdbc_connection
172
-
173
174
  #TODO return false and let the plugin raise a LogStash::ConfigurationError
174
175
  raise e
175
176
  end
@@ -208,9 +209,9 @@ module LogStash module PluginMixins module Jdbc
208
209
  public
209
210
  def execute_statement
210
211
  success = false
211
- @connection_lock.lock
212
- open_jdbc_connection
213
212
  begin
213
+ @connection_lock.lock
214
+ open_jdbc_connection
214
215
  sql_last_value = @use_column_value ? @value_tracker.value : Time.now.utc
215
216
  @tracking_column_warning_sent = false
216
217
  @statement_handler.perform_query(@database, @value_tracker.value, @jdbc_paging_enabled, @jdbc_page_size) do |row|
@@ -3,7 +3,15 @@
3
3
  module LogStash module PluginMixins module Jdbc
4
4
  class StatementHandler
5
5
  def self.build_statement_handler(plugin, logger)
6
- klass = plugin.use_prepared_statements ? PreparedStatementHandler : NormalStatementHandler
6
+ if plugin.use_prepared_statements
7
+ klass = PreparedStatementHandler
8
+ else
9
+ if plugin.jdbc_paging_enabled && plugin.jdbc_paging_mode == "explicit"
10
+ klass = ExplicitPagingModeStatementHandler
11
+ else
12
+ klass = NormalStatementHandler
13
+ end
14
+ end
7
15
  klass.new(plugin, logger)
8
16
  end
9
17
 
@@ -27,7 +35,9 @@ module LogStash module PluginMixins module Jdbc
27
35
  class NormalStatementHandler < StatementHandler
28
36
  # Performs the query, respecting our pagination settings, yielding once per row of data
29
37
  # @param db [Sequel::Database]
30
- # @param sql_last_value [Integet|DateTime|Time]
38
+ # @param sql_last_value [Integer|DateTime|Time]
39
+ # @param jdbc_paging_enabled [Boolean]
40
+ # @param jdbc_page_size [Integer]
31
41
  # @yieldparam row [Hash{Symbol=>Object}]
32
42
  def perform_query(db, sql_last_value, jdbc_paging_enabled, jdbc_page_size)
33
43
  query = build_query(db, sql_last_value)
@@ -67,6 +77,28 @@ module LogStash module PluginMixins module Jdbc
67
77
  end
68
78
  end
69
79
 
80
+ class ExplicitPagingModeStatementHandler < NormalStatementHandler
81
+ # Performs the query, respecting our pagination settings, yielding once per row of data
82
+ # @param db [Sequel::Database]
83
+ # @param sql_last_value [Integer|DateTime|Time]
84
+ # @param jdbc_paging_enabled [Boolean]
85
+ # @param jdbc_page_size [Integer]
86
+ # @yieldparam row [Hash{Symbol=>Object}]
87
+ def perform_query(db, sql_last_value, jdbc_paging_enabled, jdbc_page_size)
88
+ query = build_query(db, sql_last_value)
89
+ offset = 0
90
+ loop do
91
+ rows_in_page = 0
92
+ query.with_sql(query.sql, offset: offset, size: jdbc_page_size).each do |row|
93
+ yield row
94
+ rows_in_page += 1
95
+ end
96
+ break unless rows_in_page == jdbc_page_size
97
+ offset += jdbc_page_size
98
+ end
99
+ end
100
+ end
101
+
70
102
  class PreparedStatementHandler < StatementHandler
71
103
  attr_reader :name, :bind_values_array, :statement_prepared, :prepared
72
104
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-jdbc'
3
- s.version = '5.1.6'
3
+ s.version = '5.2.0'
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"
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
41
41
  s.add_runtime_dependency "logstash-mixin-event_support", '~> 1.0'
42
42
 
43
43
  s.add_development_dependency "childprocess"
44
- s.add_development_dependency 'logstash-devutils'
44
+ s.add_development_dependency 'logstash-devutils', '>= 2.3'
45
45
  s.add_development_dependency 'timecop'
46
46
  s.add_development_dependency 'jdbc-derby'
47
47
  end
@@ -66,13 +66,13 @@ describe LogStash::Inputs::Jdbc, :integration => true do
66
66
  )
67
67
  end
68
68
 
69
- it "should not register correctly" do
69
+ it "log warning msg when plugin run" do
70
70
  plugin.register
71
- allow( plugin ).to receive(:log_java_exception)
71
+ expect( plugin ).to receive(:log_java_exception)
72
+ expect(plugin.logger).to receive(:warn).once.with("Exception when executing JDBC query",
73
+ hash_including(:exception => instance_of(String)))
72
74
  q = Queue.new
73
- expect do
74
- plugin.run(q)
75
- end.to raise_error(::Sequel::DatabaseConnectionError)
75
+ expect{ plugin.run(q) }.not_to raise_error
76
76
  end
77
77
 
78
78
  it "should log (native) Java driver error" do
@@ -85,9 +85,7 @@ describe LogStash::Inputs::Jdbc, :integration => true do
85
85
  logger
86
86
  end
87
87
  q = Queue.new
88
- expect do
89
- plugin.run(q)
90
- end.to raise_error(::Sequel::DatabaseConnectionError)
88
+ expect{ plugin.run(q) }.not_to raise_error
91
89
  end
92
90
  end
93
91
  end
@@ -14,10 +14,11 @@ require "date"
14
14
 
15
15
  describe LogStash::Inputs::Jdbc do
16
16
  let(:connection_string) { "jdbc:derby:memory:testdb;create=true" }
17
+ let(:jdbc_driver_class) { "org.apache.derby.jdbc.EmbeddedDriver" }
17
18
  let(:mixin_settings) do
18
19
  {
19
20
  "jdbc_user" => ENV['USER'],
20
- "jdbc_driver_class" => "org.apache.derby.jdbc.EmbeddedDriver",
21
+ "jdbc_driver_class" => jdbc_driver_class,
21
22
  "jdbc_connection_string" => connection_string
22
23
  }
23
24
  end
@@ -328,6 +329,39 @@ describe LogStash::Inputs::Jdbc do
328
329
 
329
330
  end
330
331
 
332
+ context "when iterating result-set via explicit paging mode" do
333
+
334
+ let(:settings) do
335
+ {
336
+ "statement" => "SELECT * from test_table OFFSET :offset ROWS FETCH NEXT :size ROWS ONLY",
337
+ "jdbc_paging_enabled" => true,
338
+ "jdbc_paging_mode" => "explicit",
339
+ "jdbc_page_size" => 10
340
+ }
341
+ end
342
+
343
+ let(:num_rows) { 15 }
344
+
345
+ before do
346
+ plugin.register
347
+ end
348
+
349
+ after do
350
+ plugin.stop
351
+ end
352
+
353
+ it "should fetch all rows" do
354
+ num_rows.times do
355
+ db[:test_table].insert(:num => 1, :custom_time => Time.now.utc, :created_at => Time.now.utc)
356
+ end
357
+
358
+ plugin.run(queue)
359
+
360
+ expect(queue.size).to eq(num_rows)
361
+ end
362
+
363
+ end
364
+
331
365
  context "when using target option" do
332
366
  let(:settings) do
333
367
  {
@@ -1392,10 +1426,8 @@ describe LogStash::Inputs::Jdbc do
1392
1426
  event = queue.pop
1393
1427
  expect(event.get("num")).to eq(1)
1394
1428
  expect(event.get("string")).to eq("A test")
1395
- expect(event.get("started_at")).to be_a(LogStash::Timestamp)
1396
- expect(event.get("started_at").to_s).to eq("1999-12-31T00:00:00.000Z")
1397
- expect(event.get("custom_time")).to be_a(LogStash::Timestamp)
1398
- expect(event.get("custom_time").to_s).to eq("1999-12-31T23:59:59.000Z")
1429
+ expect(event.get("started_at")).to be_a_logstash_timestamp_equivalent_to("1999-12-31T00:00:00.000Z")
1430
+ expect(event.get("custom_time")).to be_a_logstash_timestamp_equivalent_to("1999-12-31T23:59:59.000Z")
1399
1431
  expect(event.get("ranking").to_f).to eq(95.67)
1400
1432
  end
1401
1433
  end
@@ -1441,10 +1473,8 @@ describe LogStash::Inputs::Jdbc do
1441
1473
  event = queue.pop
1442
1474
  expect(event.get("num")).to eq(1)
1443
1475
  expect(event.get("string")).to eq("A test")
1444
- expect(event.get("started_at")).to be_a(LogStash::Timestamp)
1445
- expect(event.get("started_at").to_s).to eq("1999-12-31T00:00:00.000Z")
1446
- expect(event.get("custom_time")).to be_a(LogStash::Timestamp)
1447
- expect(event.get("custom_time").to_s).to eq("1999-12-31T23:59:59.000Z")
1476
+ expect(event.get("started_at")).to be_a_logstash_timestamp_equivalent_to("1999-12-31T00:00:00.000Z")
1477
+ expect(event.get("custom_time")).to be_a_logstash_timestamp_equivalent_to("1999-12-31T23:59:59.000Z")
1448
1478
  expect(event.get("ranking").to_f).to eq(95.67)
1449
1479
  end
1450
1480
  end
@@ -1619,4 +1649,40 @@ describe LogStash::Inputs::Jdbc do
1619
1649
  end
1620
1650
  end
1621
1651
  end
1652
+
1653
+ describe "jdbc_driver_class" do
1654
+ context "when not prefixed with Java::" do
1655
+ let(:jdbc_driver_class) { "org.apache.derby.jdbc.EmbeddedDriver" }
1656
+ it "loads the class" do
1657
+ expect { plugin.send(:load_driver) }.not_to raise_error
1658
+ end
1659
+ end
1660
+ context "when prefixed with Java::" do
1661
+ let(:jdbc_driver_class) { "Java::org.apache.derby.jdbc.EmbeddedDriver" }
1662
+ it "loads the class" do
1663
+ expect { plugin.send(:load_driver) }.not_to raise_error
1664
+ end
1665
+ end
1666
+ context "when prefixed with Java." do
1667
+ let(:jdbc_driver_class) { "Java.org::apache::derby::jdbc.EmbeddedDriver" }
1668
+ it "loads the class" do
1669
+ expect { plugin.send(:load_driver) }.not_to raise_error
1670
+ end
1671
+
1672
+ it "can instantiate the returned driver class" do
1673
+ # for drivers where the path through DriverManager fails, Sequel assumes
1674
+ # having a proxied Java class instance (instead of a java.lang.Class) and
1675
+ # does a driver.new.connect https://git.io/JDV6M
1676
+ driver = plugin.send(:load_driver)
1677
+ expect { driver.new }.not_to raise_error
1678
+ end
1679
+ end
1680
+ context "when class name invalid" do
1681
+ let(:jdbc_driver_class) { "org.apache.NonExistentDriver" }
1682
+ it "raises a loading error" do
1683
+ expect { plugin.send(:load_driver) }.to raise_error LogStash::PluginLoadingError,
1684
+ /java.lang.ClassNotFoundException: org.apache.NonExistentDriver/
1685
+ end
1686
+ end
1687
+ end
1622
1688
  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.1.6
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-12 00:00:00.000000000 Z
11
+ date: 2021-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -203,7 +203,7 @@ dependencies:
203
203
  requirements:
204
204
  - - ">="
205
205
  - !ruby/object:Gem::Version
206
- version: '0'
206
+ version: '2.3'
207
207
  name: logstash-devutils
208
208
  prerelease: false
209
209
  type: :development
@@ -211,7 +211,7 @@ dependencies:
211
211
  requirements:
212
212
  - - ">="
213
213
  - !ruby/object:Gem::Version
214
- version: '0'
214
+ version: '2.3'
215
215
  - !ruby/object:Gem::Dependency
216
216
  requirement: !ruby/object:Gem::Requirement
217
217
  requirements: