Skip to content

Commit c06e319

Browse files
authored
Updates for JRuby 9.4 (#125)
This PR laid down adaptations to run this plugin under JRuby 9.4 (Ruby 3.1) List of changes: - in a method with var args the hash map has to be defined when passed as argument, d19fc58 Ruby 3.0 - Ruby 3.1 comes with Psych 4 which switched the alias of load from unsafe_load to safe_load reference. Created a wrapper method to behave consistently across different versions of JRuby. - fixed a stubbing error in tests: 72a2af5 - covered ValueTracker with unit tests
1 parent 69786f4 commit c06e319

File tree

6 files changed

+144
-15
lines changed

6 files changed

+144
-15
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 5.4.4
2+
- Fix: adaptations for JRuby 9.4 [#125](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/125)
3+
14
## 5.4.3
25
- Fix crash when metadata file can't be deleted after moving under path.data [#136](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/136)
36

lib/logstash/plugin_mixins/jdbc/value_tracking.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# encoding: utf-8
22
require "yaml" # persistence
3+
require "date"
4+
require "bigdecimal"
35

46
module LogStash module PluginMixins module Jdbc
57
class ValueTracking
@@ -31,6 +33,17 @@ def initialize(handler)
3133
set_initial
3234
end
3335

36+
if Psych::VERSION&.split('.')&.first.to_i >= 4
37+
YAML_PERMITTED_CLASSES = [::DateTime, ::Time, ::BigDecimal].freeze
38+
def self.load_yaml(source)
39+
Psych::safe_load(source, permitted_classes: YAML_PERMITTED_CLASSES)
40+
end
41+
else
42+
def self.load_yaml(source)
43+
YAML::load(source)
44+
end
45+
end
46+
3447
def set_initial
3548
# override in subclass
3649
end
@@ -112,7 +125,7 @@ def clean
112125

113126
def read
114127
return unless @exists
115-
YAML.load(::File.read(@path))
128+
ValueTracking.load_yaml(::File.read(@path))
116129
end
117130

118131
def write(value)

logstash-integration-jdbc.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |s|
22
s.name = 'logstash-integration-jdbc'
3-
s.version = '5.4.3'
3+
s.version = '5.4.4'
44
s.licenses = ['Apache License (2.0)']
55
s.summary = "Integration with JDBC - input and filter plugins"
66
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"

spec/filters/jdbc_streaming_spec.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ class TestJdbcStreaming < JdbcStreaming
259259
CONFIG
260260
end
261261

262-
sample("message" => "some text") do
262+
sample({"message" => "some text"}) do
263263
expect(subject.get('new_field')).to eq([{"1" => 'from_database'}])
264264
end
265265
end
@@ -277,7 +277,7 @@ class TestJdbcStreaming < JdbcStreaming
277277
CONFIG
278278
end
279279

280-
sample("message" => "some text") do
280+
sample({"message" => "some text"}) do
281281
expect(subject.get('new_field')).to eq([{"col_1" => 'from_database'}])
282282
end
283283
end
@@ -296,11 +296,11 @@ class TestJdbcStreaming < JdbcStreaming
296296
CONFIG
297297
end
298298

299-
sample("message" => "some text", "param_field" => "1") do
299+
sample({"message" => "some text", "param_field" => "1"}) do
300300
expect(subject.get('new_field')).to eq([{"1" => 'from_database'}])
301301
end
302302

303-
sample("message" => "some text", "param_field" => "2") do
303+
sample({"message" => "some text", "param_field" => "2"}) do
304304
expect(subject.get('new_field').nil?)
305305
end
306306
end
@@ -319,11 +319,11 @@ class TestJdbcStreaming < JdbcStreaming
319319
CONFIG
320320
end
321321

322-
sample("message" => "some text", "param_field" => 1) do
322+
sample({"message" => "some text", "param_field" => 1}) do
323323
expect(subject.get('new_field')).to eq([{"1" => 'from_database'}])
324324
end
325325

326-
sample("message" => "some text", "param_field" => "1") do
326+
sample({"message" => "some text", "param_field" => "1"}) do
327327
expect(subject.get('new_field').nil?)
328328
end
329329
end
@@ -342,7 +342,7 @@ class TestJdbcStreaming < JdbcStreaming
342342
CONFIG
343343
end
344344

345-
sample("message" => "some text") do
345+
sample({"message" => "some text"}) do
346346
expect(subject.get('new_field')).to eq([{"1" => 'from_database'}])
347347
end
348348
end

spec/inputs/jdbc_spec.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@
277277
sleep 1
278278
for i in 0..1
279279
sleep 1
280-
updated_last_run = YAML.load(File.read(settings["last_run_metadata_path"]))
280+
updated_last_run = LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(File.read(settings["last_run_metadata_path"]))
281281
expect(updated_last_run).to be > last_run_time
282282
last_run_time = updated_last_run
283283
end
@@ -547,7 +547,7 @@
547547
expect(actual).to eq(expected)
548548
plugin.stop
549549
raw_last_run_value = File.read(settings["last_run_metadata_path"])
550-
last_run_value = YAML.load(raw_last_run_value)
550+
last_run_value = LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(raw_last_run_value)
551551
expect(last_run_value).to be_a(DateTime)
552552
expect(last_run_value.strftime("%F %T.%N %Z")).to eq("2015-01-02 02:00:00.722000000 +00:00")
553553

@@ -562,7 +562,7 @@
562562
plugin.stop
563563
expect(event.get("num")).to eq(12)
564564
expect(event.get("custom_time").time).to eq(Time.iso8601("2015-01-02T03:00:00.811Z"))
565-
last_run_value = YAML.load(File.read(settings["last_run_metadata_path"]))
565+
last_run_value = LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(File.read(settings["last_run_metadata_path"]))
566566
expect(last_run_value).to be_a(DateTime)
567567
# verify that sub-seconds are recorded to the file
568568
expect(last_run_value.strftime("%F %T.%N %Z")).to eq("2015-01-02 03:00:00.811000000 +00:00")
@@ -1169,7 +1169,7 @@
11691169
context "when a file exists" do
11701170
before do
11711171
# in a faked HOME folder save a valid previous last_run metadata file
1172-
allow(ENV).to receive(:[]).and_call_original
1172+
allow(ENV).to receive(:[]).with(anything).and_call_original
11731173
allow(ENV).to receive(:[]).with('HOME').and_return(fake_home)
11741174

11751175
File.open("#{fake_home}/.logstash_jdbc_last_run", 'w') do |file|
@@ -1722,7 +1722,7 @@
17221722
plugin.run(queue)
17231723

17241724
expect(queue.size).to eq(expected_queue_size)
1725-
expect(YAML.load(File.read(settings["last_run_metadata_path"]))).to eq(expected_queue_size)
1725+
expect(LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(File.read(settings["last_run_metadata_path"]))).to eq(expected_queue_size)
17261726
end
17271727
end
17281728

@@ -1747,7 +1747,7 @@
17471747
plugin.run(queue)
17481748

17491749
expect(queue.size).to eq(expected_queue_size)
1750-
expect(YAML.load(File.read(settings["last_run_metadata_path"]))).to eq(last_run_value + expected_queue_size)
1750+
expect(LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(File.read(settings["last_run_metadata_path"]))).to eq(last_run_value + expected_queue_size)
17511751
end
17521752
end
17531753
end
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# encoding: utf-8
2+
require "logstash/plugin_mixins/jdbc/value_tracking"
3+
require "tempfile"
4+
5+
module LogStash module PluginMixins module Jdbc
6+
describe ValueTracking do
7+
context "#load_yaml" do
8+
9+
context "with date string" do
10+
let(:yaml_date_source) { "--- !ruby/object:DateTime '2023-06-15 09:59:30.558000000 +02:00'\n" }
11+
12+
it "should be loaded" do
13+
parsed_date = LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(yaml_date_source)
14+
expect(parsed_date.class).to eq DateTime
15+
expect(parsed_date.year).to eq 2023
16+
expect(parsed_date.month).to eq 6
17+
expect(parsed_date.day).to eq 15
18+
end
19+
end
20+
21+
context "with time string" do
22+
let(:yaml_time_source) { "--- 2023-06-15 15:28:15.227874000 +02:00\n" }
23+
24+
it "should be loaded" do
25+
parsed_time = LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(yaml_time_source)
26+
expect(parsed_time.class).to eq Time
27+
expect(parsed_time.year).to eq 2023
28+
expect(parsed_time.month).to eq 6
29+
expect(parsed_time.day).to eq 15
30+
expect(parsed_time.hour).to eq 15
31+
expect(parsed_time.min).to eq 28
32+
expect(parsed_time.sec).to eq 15
33+
end
34+
end
35+
36+
context "with date string" do
37+
let(:yaml_bigdecimal_source) { "--- !ruby/object:BigDecimal '0:0.1e1'\n" }
38+
39+
it "should be loaded" do
40+
parsed_bigdecimal = LogStash::PluginMixins::Jdbc::ValueTracking.load_yaml(yaml_bigdecimal_source)
41+
expect(parsed_bigdecimal.class).to eq BigDecimal
42+
expect(parsed_bigdecimal.to_i).to eq 1
43+
end
44+
end
45+
end
46+
47+
context "#build_last_value_tracker" do
48+
49+
let(:plugin) { double("fake plugin") }
50+
let(:temp_file) { Tempfile.new('last_run_tracker') }
51+
52+
before(:each) do
53+
allow(plugin).to receive(:record_last_run).and_return(true)
54+
allow(plugin).to receive(:clean_run).and_return(false)
55+
allow(plugin).to receive(:last_run_metadata_file_path).and_return(temp_file.path)
56+
end
57+
58+
context "create numerical tracker" do
59+
before(:each) do
60+
allow(plugin).to receive(:use_column_value).and_return(true)
61+
allow(plugin).to receive(:tracking_column_type).and_return("numeric")
62+
end
63+
64+
it "should write correctly" do
65+
tracker = ValueTracking.build_last_value_tracker(plugin)
66+
tracker.set_value(1)
67+
tracker.write
68+
69+
temp_file.rewind
70+
v = ValueTracking.load_yaml(::File.read(temp_file.path))
71+
expect(v).to eq 1
72+
end
73+
end
74+
75+
context "create date time tracker" do
76+
before(:each) do
77+
allow(plugin).to receive(:use_column_value).and_return(false)
78+
allow(plugin).to receive(:jdbc_default_timezone).and_return(:something_not_nil)
79+
end
80+
81+
it "should write correctly" do
82+
tracker = ValueTracking.build_last_value_tracker(plugin)
83+
tracker.set_value("2023-06-15T15:28:15+02:00")
84+
tracker.write
85+
86+
temp_file.rewind
87+
v = ValueTracking.load_yaml(::File.read(temp_file.path))
88+
expect(v.class).to eq DateTime
89+
expect(v.year).to eq 2023
90+
end
91+
end
92+
93+
context "create time tracker" do
94+
before(:each) do
95+
allow(plugin).to receive(:use_column_value).and_return(false)
96+
allow(plugin).to receive(:jdbc_default_timezone).and_return(nil)
97+
end
98+
99+
it "should write correctly" do
100+
tracker = ValueTracking.build_last_value_tracker(plugin)
101+
tracker.set_value("2023-06-15T15:28:15+02:00")
102+
tracker.write
103+
104+
temp_file.rewind
105+
v = ValueTracking.load_yaml(::File.read(temp_file.path))
106+
expect(v.class).to eq Time
107+
expect(v.min).to eq 28
108+
end
109+
end
110+
111+
end
112+
end
113+
end end end

0 commit comments

Comments
 (0)