logstash-integration-jdbc 5.2.5 → 5.2.6

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: b74796568bc1df12ae5015cfcf38aeb43971b3bd3eda2dcc668104decc69b6a2
4
- data.tar.gz: ae3a1f82f7354798692933a2426977ea2e17f7335a74d02eb09a376e4421af6b
3
+ metadata.gz: c9cc41a07a8cb2f7e4b9a6993dd4d0cd69761b3fa95ba81238d0dd6267367311
4
+ data.tar.gz: 32866a340d87d91734586b3324a1349437abc624deb6ff9883ab998b0a4524a6
5
5
  SHA512:
6
- metadata.gz: d198c08e74dc4702dae5de1ca4661d68d10298ff497e44739e7cc775d575bfc9fe825154a9de6f2497e60fb3c694f06d36d8971ecf9935e13592c959d6c13c53
7
- data.tar.gz: ccd725393201ec5282644f003880fa0449a027942442698fe6e1758f25335ff585efb73d0f52716c9698eb19990ef67a15b21fef90255473b39683339520796a
6
+ metadata.gz: b3513ba2d9ade38a829ec0b0c47ad6c0978d0256e03fb4ac26e136a064db65b08a19b7ee8dd7dabe26851739877b82f0f9a550b2328473b8ffd62f194d569ebb
7
+ data.tar.gz: bf71a208f07bc00c213724cbcf175a9ede2f87bf4eaf85a926ee8e9f87b322e2dd79164db1db84ec60633a0b1cfa961e8fc6d3889c8ca25ea220fa437285af5d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 5.2.6
2
+ - Fix: change default path of 'last_run_metadata_path' to be rooted in the LS data.path folder and not in $HOME [#106](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/106)
3
+
1
4
  ## 5.2.5
2
5
  - Fix: do not execute more queries with debug logging [#109](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/109)
3
6
 
@@ -175,9 +175,23 @@ module LogStash module Filters class JdbcStatic < LogStash::Filters::Base
175
175
  private
176
176
 
177
177
  def prepare_data_dir
178
+ # cleanup existing Derby file left behind in $HOME
179
+ derby_log = "#{ENV['HOME']}/derby.log"
180
+ if ::File.exist?(derby_log)
181
+ begin
182
+ ::File.delete(derby_log)
183
+ rescue Errno::EPERM => e
184
+ @logger.warn("Can't delete temporary file #{derby_log} due to access permissions")
185
+ rescue e
186
+ @logger.warn("Can't delete temporary file #{derby_log}", {message => e.message})
187
+ end
188
+ end
189
+
178
190
  # later, when local persistent databases are allowed set this property to LS_HOME/data/jdbc-static/
179
191
  # must take multi-pipelines into account and more than one config using the same jdbc-static settings
180
- java.lang.System.setProperty("derby.system.home", ENV["HOME"])
192
+ path_data = Pathname.new(LogStash::SETTINGS.get_value("path.data")).join("plugins", "shared", "derby_home")
193
+ path_data.mkpath
194
+ java.lang.System.setProperty("derby.system.home", path_data.to_path)
181
195
  logger.info("derby.system.home is: #{java.lang.System.getProperty("derby.system.home")}")
182
196
  end
183
197
 
@@ -9,6 +9,7 @@ require "logstash/plugin_mixins/ecs_compatibility_support/target_check"
9
9
  require "logstash/plugin_mixins/validator_support/field_reference_validation_adapter"
10
10
 
11
11
  require "logstash/plugin_mixins/event_support/event_factory_adapter"
12
+ require "fileutils"
12
13
 
13
14
  # this require_relative returns early unless the JRuby version is between 9.2.0.0 and 9.2.8.0
14
15
  require_relative "tzinfo_jruby_patch"
@@ -178,8 +179,10 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
178
179
  # exactly once.
179
180
  config :schedule, :validate => :string
180
181
 
181
- # Path to file with last run time
182
- config :last_run_metadata_path, :validate => :string, :default => "#{ENV['HOME']}/.logstash_jdbc_last_run"
182
+ # Path to file with last run time.
183
+ # The default will write file to `<path.data>/plugins/inputs/jdbc/logstash_jdbc_last_run`
184
+ # NOTE: it must be a file path and not a directory path
185
+ config :last_run_metadata_path, :validate => :string
183
186
 
184
187
  # Use an incremental column value rather than a timestamp
185
188
  config :use_column_value, :validate => :boolean, :default => false
@@ -230,11 +233,33 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
230
233
  config :target, :validate => :field_reference, :required => false
231
234
 
232
235
  attr_reader :database # for test mocking/stubbing
236
+ attr_reader :last_run_metadata_file_path # path to the file used as last run storage
233
237
 
234
238
  public
235
239
 
236
240
  def register
237
241
  @logger = self.logger
242
+
243
+ if @record_last_run
244
+ if @last_run_metadata_path.nil?
245
+ logstash_data_path = LogStash::SETTINGS.get_value("path.data")
246
+ logstash_data_path = Pathname.new(logstash_data_path).join("plugins", "inputs", "jdbc")
247
+ # Ensure that the filepath exists before writing, since it's deeply nested.
248
+ logstash_data_path.mkpath
249
+ logstash_data_file_path = logstash_data_path.join("logstash_jdbc_last_run")
250
+
251
+ ensure_default_metadatafile_location(logstash_data_file_path)
252
+
253
+ @last_run_metadata_file_path = logstash_data_file_path.to_path
254
+ else
255
+ # validate the path is a file and not a directory
256
+ if Pathname.new(@last_run_metadata_path).directory?
257
+ raise LogStash::ConfigurationError.new("The \"last_run_metadata_path\" argument must point to a file, received a directory: \"#{last_run_metadata_path}\"")
258
+ end
259
+ @last_run_metadata_file_path = @last_run_metadata_path
260
+ end
261
+ end
262
+
238
263
  require "rufus/scheduler"
239
264
  prepare_jdbc_connection
240
265
 
@@ -363,4 +388,23 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
363
388
  value
364
389
  end
365
390
  end
391
+
392
+ def ensure_default_metadatafile_location(metadata_new_path)
393
+ old_default_path = Pathname.new("#{ENV['HOME']}/.logstash_jdbc_last_run")
394
+
395
+ if old_default_path.exist? && !metadata_new_path.exist?
396
+ # Previous versions of the plugin hosted the state file into $HOME/.logstash_jdbc_last_run.
397
+ # Copy in the new location
398
+ FileUtils.cp(old_default_path.to_path, metadata_new_path.to_path)
399
+ begin
400
+ # If there is a permission error in the delete of the old file inform the user to give
401
+ # the correct access rights
402
+ ::File.delete(old_default_path.to_path)
403
+ @logger.info("Successfully moved the #{old_default_path.to_path} into #{metadata_new_path.to_path}")
404
+ rescue e
405
+ @logger.warn("Using new metadata file at #{metadata_new_path.to_path} but #{old_default_path} can't be removed.")
406
+ end
407
+ end
408
+ end
409
+
366
410
  end end end # class LogStash::Inputs::Jdbc
@@ -5,7 +5,7 @@ module LogStash module PluginMixins module Jdbc
5
5
  class ValueTracking
6
6
 
7
7
  def self.build_last_value_tracker(plugin)
8
- handler = plugin.record_last_run ? FileHandler.new(plugin.last_run_metadata_path) : NullFileHandler.new(plugin.last_run_metadata_path)
8
+ handler = plugin.record_last_run ? FileHandler.new(plugin.last_run_metadata_file_path) : NullFileHandler.new(plugin.last_run_metadata_file_path)
9
9
  if plugin.clean_run
10
10
  handler.clean
11
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.5'
3
+ s.version = '5.2.6'
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"
@@ -5,6 +5,7 @@ require "sequel"
5
5
  require "sequel/adapters/jdbc"
6
6
  require "stud/temporary"
7
7
  require "timecop"
8
+ require "pathname"
8
9
 
9
10
  # LogStash::Logging::Logger::configure_logging("WARN")
10
11
 
@@ -85,6 +86,15 @@ module LogStash module Filters
85
86
 
86
87
  let(:ipaddr) { ".3.1.1" }
87
88
 
89
+ describe "verify derby path property" do
90
+ it "should be set into Logstash data path" do
91
+ plugin.register
92
+
93
+ expected = Pathname.new(LogStash::SETTINGS.get_value("path.data")).join("plugins", "shared", "derby_home").to_path
94
+ expect(java.lang.System.getProperty("derby.system.home")).to eq(expected)
95
+ end
96
+ end
97
+
88
98
  describe "non scheduled operation" do
89
99
  after { plugin.close }
90
100
 
@@ -9,6 +9,7 @@ require "timecop"
9
9
  require "stud/temporary"
10
10
  require "time"
11
11
  require "date"
12
+ require "pathname"
12
13
 
13
14
  # We do not need to set TZ env var anymore because we can have 'Sequel.application_timezone' set to utc by default now.
14
15
 
@@ -51,6 +52,9 @@ describe LogStash::Inputs::Jdbc do
51
52
  db.drop_table(:types_table)
52
53
  db.drop_table(:test1_table)
53
54
  end
55
+
56
+ last_run_default_path = LogStash::SETTINGS.get_value("path.data")
57
+ FileUtils.rm_f("#{last_run_default_path}/plugins/inputs/jdbc/logstash_jdbc_last_run")
54
58
  end
55
59
 
56
60
  context "when registering and tearing down" do
@@ -1114,6 +1118,86 @@ describe LogStash::Inputs::Jdbc do
1114
1118
  end
1115
1119
  end
1116
1120
 
1121
+ context "when state is persisted" do
1122
+ context "to file" do
1123
+ let(:settings) do
1124
+ {
1125
+ "statement" => "SELECT * FROM test_table",
1126
+ "record_last_run" => true
1127
+ }
1128
+ end
1129
+
1130
+ before do
1131
+ plugin.register
1132
+ end
1133
+
1134
+ after do
1135
+ plugin.stop
1136
+ end
1137
+
1138
+ context "with default last_run_metadata_path" do
1139
+ it "should save state in data.data subpath" do
1140
+ path = LogStash::SETTINGS.get_value("path.data")
1141
+ expect(plugin.last_run_metadata_file_path).to start_with(path)
1142
+ end
1143
+ end
1144
+
1145
+ context "with customized last_run_metadata_path" do
1146
+ let(:settings) { super().merge({ "last_run_metadata_path" => Stud::Temporary.pathname })}
1147
+
1148
+ it "should save state in data.data subpath" do
1149
+ expect(plugin.last_run_metadata_file_path).to start_with(settings["last_run_metadata_path"])
1150
+ end
1151
+ end
1152
+ end
1153
+
1154
+ context "with customized last_run_metadata_path point to directory" do
1155
+ let(:settings) do
1156
+ path = Stud::Temporary.pathname
1157
+ Pathname.new(path).tap {|path| path.mkpath}
1158
+ super().merge({ "last_run_metadata_path" => path})
1159
+ end
1160
+
1161
+ it "raise configuration error" do
1162
+ expect { plugin.register }.to raise_error(LogStash::ConfigurationError)
1163
+ end
1164
+ end
1165
+ end
1166
+
1167
+ context "update the previous default last_run_metadata_path" do
1168
+ let(:settings) do
1169
+ {
1170
+ "statement" => "SELECT * FROM test_table",
1171
+ "record_last_run" => true
1172
+ }
1173
+ end
1174
+
1175
+ let(:fake_home) do
1176
+ path = Stud::Temporary.pathname
1177
+ Pathname.new(path).tap {|path| path.mkpath}
1178
+ path
1179
+ end
1180
+
1181
+ context "when a file exists" do
1182
+ before do
1183
+ # in a faked HOME folder save a valid previous last_run metadata file
1184
+ allow(ENV).to receive(:[]).with('HOME').and_return(fake_home)
1185
+ File.open("#{ENV['HOME']}/.logstash_jdbc_last_run", 'w') do |file|
1186
+ file.write("--- !ruby/object:DateTime '2022-03-08 08:10:00.486889000 Z'")
1187
+ end
1188
+ end
1189
+
1190
+ it "should be moved" do
1191
+ plugin.register
1192
+
1193
+ expect(::File.exist?("#{ENV['HOME']}/.logstash_jdbc_last_run")).to be false
1194
+ path = LogStash::SETTINGS.get_value("path.data")
1195
+ full_path = "#{path}/plugins/inputs/jdbc/logstash_jdbc_last_run"
1196
+ expect(::File.exist?(full_path)).to be true
1197
+ end
1198
+ end
1199
+ end
1200
+
1117
1201
  context "when setting fetch size" do
1118
1202
 
1119
1203
  let(:settings) do
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.5
4
+ version: 5.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-16 00:00:00.000000000 Z
11
+ date: 2022-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement