logstash-integration-jdbc 5.6.3 → 5.6.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: 9afa5771b7e338b50c59cd6f2bd3d28fa23a5ac2df2804fedbde7f372d52c54f
4
- data.tar.gz: a50c4f2c24c347363f4398ef0fe8584c6db86fcf6ff9f1bafccdf82ef1989226
3
+ metadata.gz: b0434f8f19d3cb7df52955e6263c639acbf7edf1e8007f6eca2f0428c63d7794
4
+ data.tar.gz: 1a741166ce8d2e83a1d32d727448042fd2fd3b801635528b67c40ca79733f608
5
5
  SHA512:
6
- metadata.gz: 76770166eb5ea2b20758e75d223998bc45d29b0fcc2e78864af6ca936db98c40075be88bbb9292c9473663d734c6be700e9ef5500dc7c5beaa03dcf078ec4a5a
7
- data.tar.gz: 3a91177b9028fa7e956c8b4b100bfc20ecd18ea5451e7c625f3d31cce6ae952fdb9c2eb724dbb767fa606dc88c93fec87a55ef4dff37eff0b2b394ab4c7ff232
6
+ metadata.gz: 514915aa797a46b5ec6f167c69809773f110a848bfbd98a874f71fc6e145517c268768ecb1240bd82346ce9d26350f9e66ce1d3f1e39c07dc7b437410d061032
7
+ data.tar.gz: eb4a71bdc9b67344f53ccf7a2502c50108e0ea2a746fa204b4f52a314c487def7fe9ae5cc3679f7811a7842f2e270e97ef1c281619309637b1f7fda0ee506f9c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 5.6.4
2
+ - Fix connection leak on statement retry by opening JDBC connection once outside retry loop [#201](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/201)
3
+
1
4
  ## 5.6.3
2
5
  - Fix: replace deprecated `File.exists?` with `File.exist?` for Ruby 3.4 (JRuby 10) compatibility [#192](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/192)
3
6
 
@@ -160,6 +160,13 @@ module LogStash module PluginMixins module Jdbc
160
160
  logger.error('', e) # prints nested causes
161
161
  end
162
162
 
163
+ def log_jdbc_query_exception(e)
164
+ details = { exception: e.class, message: e.message }
165
+ details[:cause] = e.cause.inspect if e.cause
166
+ details[:backtrace] = e.backtrace if @logger.debug?
167
+ @logger.warn("Exception when executing JDBC query", details)
168
+ end
169
+
163
170
  def open_jdbc_connection
164
171
  @connection_lock.synchronize do
165
172
  # at this point driver is already loaded
@@ -222,30 +229,31 @@ module LogStash module PluginMixins module Jdbc
222
229
 
223
230
  @connection_lock.synchronize do
224
231
  begin
225
- retry_attempts -= 1
226
232
  open_jdbc_connection
227
- sql_last_value = @use_column_value ? @value_tracker.value : Time.now.utc
228
- @tracking_column_warning_sent = false
229
- @statement_handler.perform_query(@database, @value_tracker.value) do |row|
230
- sql_last_value = get_column_value(row) if @use_column_value
231
- yield extract_values_from(row)
232
- end
233
- success = true
234
- rescue Sequel::Error, Java::JavaSql::SQLException => e
235
- details = { exception: e.class, message: e.message }
236
- details[:cause] = e.cause.inspect if e.cause
237
- details[:backtrace] = e.backtrace if @logger.debug?
238
- @logger.warn("Exception when executing JDBC query", details)
239
-
240
- if retry_attempts == 0
241
- @logger.error("Unable to execute statement. Tried #{@statement_retry_attempts} times.")
233
+ begin
234
+ retry_attempts -= 1
235
+ sql_last_value = @use_column_value ? @value_tracker.value : Time.now.utc
236
+ @tracking_column_warning_sent = false
237
+ @statement_handler.perform_query(@database, @value_tracker.value) do |row|
238
+ sql_last_value = get_column_value(row) if @use_column_value
239
+ yield extract_values_from(row)
240
+ end
241
+ success = true
242
+ rescue Sequel::Error, Java::JavaSql::SQLException => e
243
+ log_jdbc_query_exception(e)
244
+
245
+ if retry_attempts == 0
246
+ @logger.error("Unable to execute statement. Tried #{@statement_retry_attempts} times.")
247
+ else
248
+ @logger.error("Unable to execute statement. Trying again.")
249
+ sleep(@statement_retry_attempts_wait_time)
250
+ retry
251
+ end
242
252
  else
243
- @logger.error("Unable to execute statement. Trying again.")
244
- sleep(@statement_retry_attempts_wait_time)
245
- retry
253
+ @value_tracker.set_value(sql_last_value)
246
254
  end
247
- else
248
- @value_tracker.set_value(sql_last_value)
255
+ rescue Sequel::Error, Java::JavaSql::SQLException => e
256
+ log_jdbc_query_exception(e)
249
257
  ensure
250
258
  close_jdbc_connection
251
259
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-jdbc'
3
- s.version = '5.6.3'
3
+ s.version = ::File.read('version').split("\n").first
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"
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.require_paths = ["lib", "vendor/jar-dependencies"]
11
11
 
12
12
  # Files
13
- s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
13
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "version", "docs/**/*"]
14
14
 
15
15
  # Tests
16
16
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
@@ -1310,7 +1310,8 @@ describe LogStash::Inputs::Jdbc do
1310
1310
  plugin.register
1311
1311
  plugin.run(queue)
1312
1312
  db = plugin.instance_variable_get(:@database)
1313
- expect(db.pool).to be_a_kind_of(::Sequel::ThreadedConnectionPool) # pries into internal details
1313
+ # Sequel defaults to TimedQueueConnectionPool on Ruby 3.2+ (JRuby 10+), ThreadedConnectionPool on older versions under the Sequel::ConnectionPool superclass
1314
+ expect(db.pool).to be_a_kind_of(::Sequel::ConnectionPool)
1314
1315
  expect(db.pool.instance_variable_get(:@timeout)).to eq(0)
1315
1316
  expect(db.pool.instance_variable_get(:@max_size)).to eq(1)
1316
1317
 
@@ -1447,6 +1448,58 @@ describe LogStash::Inputs::Jdbc do
1447
1448
  plugin.run(queue)
1448
1449
  plugin.stop
1449
1450
  end
1451
+
1452
+ it "opens the connection only once across statement retries" do
1453
+ mixin_settings['statement_retry_attempts'] = 3
1454
+ mixin_settings['statement_retry_attempts_wait_time'] = 0
1455
+ queue = Queue.new
1456
+ plugin.register
1457
+
1458
+ handler = plugin.instance_variable_get(:@statement_handler)
1459
+ allow(handler).to receive(:perform_query).and_raise(Sequel::PoolTimeout)
1460
+ allow(plugin.logger).to receive(:warn)
1461
+ allow(plugin.logger).to receive(:error)
1462
+
1463
+ expect(plugin).to receive(:open_jdbc_connection).once.and_call_original
1464
+
1465
+ plugin.run(queue)
1466
+ plugin.stop
1467
+ end
1468
+
1469
+ it "closes the connection after statement retries are exhausted" do
1470
+ mixin_settings['statement_retry_attempts'] = 2
1471
+ mixin_settings['statement_retry_attempts_wait_time'] = 0
1472
+ queue = Queue.new
1473
+ plugin.register
1474
+
1475
+ handler = plugin.instance_variable_get(:@statement_handler)
1476
+ allow(handler).to receive(:perform_query).and_raise(Sequel::PoolTimeout)
1477
+ allow(plugin.logger).to receive(:warn)
1478
+ allow(plugin.logger).to receive(:error)
1479
+
1480
+ expect(plugin).to receive(:close_jdbc_connection).at_least(:once).and_call_original
1481
+
1482
+ plugin.run(queue)
1483
+ plugin.stop
1484
+ end
1485
+
1486
+ it "closes the connection when open_jdbc_connection fails after database is assigned" do
1487
+ queue = Queue.new
1488
+ plugin.register
1489
+
1490
+ allow(plugin).to receive(:open_jdbc_connection).and_wrap_original do |m, *args|
1491
+ # simulate partial initialization: jdbc_connect succeeds but test_connection fails
1492
+ plugin.instance_variable_set(:@database, db)
1493
+ raise Sequel::DatabaseConnectionError, "test_connection failed"
1494
+ end
1495
+ allow(plugin.logger).to receive(:warn)
1496
+ allow(plugin.logger).to receive(:error)
1497
+
1498
+ expect(plugin).to receive(:close_jdbc_connection).at_least(:once).and_call_original
1499
+
1500
+ plugin.run(queue)
1501
+ plugin.stop
1502
+ end
1450
1503
  end
1451
1504
 
1452
1505
  context "when encoding of some columns need to be changed" do
data/version ADDED
@@ -0,0 +1 @@
1
+ 5.6.4
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-integration-jdbc
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.3
4
+ version: 5.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-11 00:00:00.000000000 Z
10
+ date: 2026-07-21 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: logstash-core-plugin-api
@@ -286,6 +286,7 @@ files:
286
286
  - vendor/jar-dependencies/org/apache/derby/derbyclient/10.15.2.1/derbyclient-10.15.2.1.jar
287
287
  - vendor/jar-dependencies/org/apache/derby/derbyshared/10.15.2.1/derbyshared-10.15.2.1.jar
288
288
  - vendor/jar-dependencies/org/apache/derby/derbytools/10.15.2.1/derbytools-10.15.2.1.jar
289
+ - version
289
290
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
290
291
  licenses:
291
292
  - Apache License (2.0)