logstash-input-jdbc 3.0.2 → 3.1.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
  SHA1:
3
- metadata.gz: 210deedb95591e0f409fc3461af2d79bb8a384e8
4
- data.tar.gz: 8543b8a26df1cd6a80fcace0f7c7e54be175cf2e
3
+ metadata.gz: 6212e80eff0e3db1f5f86d14b2f3222f59a35dd6
4
+ data.tar.gz: f23623cebfda1902907cb4f9fb5a460a73e362bc
5
5
  SHA512:
6
- metadata.gz: df9c7fa5e10be322919f607a815c9fe899f05da6bb348c599e2d35390f5a10b1647ea0fe8ef60c8c05cfa524b7db3e39ae89fa256f832b5972f467c17a72c462
7
- data.tar.gz: d42eccdbab0331fc8e7e834e45fb0944e22eb9e1eb583782955bf34aa7cad8aab33fe9c6c9b29f43257992f11e4e5947cd177f83d4e10cc9fb6071d80880725a
6
+ metadata.gz: 4f19afa4d410887fc49f5ec8c5ac30e7ad7f345c79c7b17c1f3aed69654814d259d1e00205b668baa93ab30a4c88cf595fd3b9b84f44f8bcb133ecbca234b201
7
+ data.tar.gz: cbda68232c8f6a7f5eddbfee91bc94d5a4f86f1a317912d85413de16f69e63e486bfa5c35ca1a804623c3b45e7021162fcea9f7fb76fae232a6de4505161a476
@@ -1,3 +1,7 @@
1
+ # 3.1.0
2
+ - Add an option to select the encoding data should be transform from, this will make sure all strings read from the jdbc connector are noremalized to be UTF-8 so no causing issues with later filters in LS.
3
+ # 3.0.3
4
+ - Added feature to read password from external file (#120).
1
5
  # 3.0.2
2
6
  - Depend on logstash-core-plugin-api instead of logstash-core, removing the need to mass update plugins on major releases of logstash
3
7
  # 3.0.1
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012–2015 Elasticsearch <http://www.elastic.co>
1
+ Copyright (c) 2012–2016 Elasticsearch <http://www.elastic.co>
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -95,6 +95,7 @@ Reading data from MySQL:
95
95
  jdbc_connection_string => "jdbc:mysql://host:port/database"
96
96
  jdbc_user => "user"
97
97
  jdbc_password => "password"
98
+ # or jdbc_password_filepath => "/path/to/my/password_file"
98
99
  statement => "SELECT ..."
99
100
  jdbc_paging_enabled => "true"
100
101
  jdbc_page_size => "50000"
@@ -160,6 +160,26 @@ class LogStash::Inputs::Jdbc < LogStash::Inputs::Base
160
160
  # Whether to force the lowercasing of identifier fields
161
161
  config :lowercase_column_names, :validate => :boolean, :default => true
162
162
 
163
+ # The character encoding of all columns, leave empty if the columns are already properly UTF-8
164
+ # encoded. Specific columns charsets using :columns_charset can override this setting.
165
+ config :charset, :validate => :string
166
+
167
+ # The character encoding for specific columns. This option will override the `:charset` option
168
+ # for the specified columns.
169
+ #
170
+ # Example:
171
+ # [source,ruby]
172
+ # ----------------------------------
173
+ # input {
174
+ # jdbc {
175
+ # ...
176
+ # columns_charset => { "column0" => "ISO-8859-1" }
177
+ # ...
178
+ # }
179
+ # }
180
+ # this will only convert column0 that has ISO-8859-1 as an original encoding.
181
+ config :columns_charset, :validate => :hash, :default => {}
182
+
163
183
  public
164
184
 
165
185
  def register
@@ -173,6 +193,8 @@ class LogStash::Inputs::Jdbc < LogStash::Inputs::Base
173
193
  end
174
194
  end
175
195
 
196
+ @enable_encoding = !@charset.nil? || !@columns_charset.empty?
197
+
176
198
  # load sql_last_value from file if exists
177
199
  if @clean_run && File.exist?(@last_run_metadata_path)
178
200
  File.delete(@last_run_metadata_path)
@@ -185,6 +207,20 @@ class LogStash::Inputs::Jdbc < LogStash::Inputs::Base
185
207
  end
186
208
 
187
209
  @statement = File.read(@statement_filepath) if @statement_filepath
210
+
211
+ if (@jdbc_password_filepath and @jdbc_password)
212
+ raise(LogStash::ConfigurationError, "Only one of :jdbc_password, :jdbc_password_filepath may be set at a time.")
213
+ end
214
+
215
+ @jdbc_password = File.read(@jdbc_password_filepath).strip if @jdbc_password_filepath
216
+
217
+ if enable_encoding?
218
+ @converters = {}
219
+ @columns_charset.each do |column_name, encoding|
220
+ @converters[encoding] = LogStash::Util::Charset.new(encoding)
221
+ end
222
+ @converters[@charset] = LogStash::Util::Charset.new(@charset) if @charset
223
+ end
188
224
  end # def register
189
225
 
190
226
  def run(queue)
@@ -214,6 +250,10 @@ class LogStash::Inputs::Jdbc < LogStash::Inputs::Base
214
250
  # update default parameters
215
251
  @parameters['sql_last_value'] = @sql_last_value
216
252
  execute_statement(@statement, @parameters) do |row|
253
+ if enable_encoding?
254
+ ## do the necessary conversions to string elements
255
+ row = Hash[row.map { |k, v| [k.to_s, convert(k, v)] }]
256
+ end
217
257
  event = LogStash::Event.new(row)
218
258
  decorate(event)
219
259
  queue << event
@@ -226,4 +266,24 @@ class LogStash::Inputs::Jdbc < LogStash::Inputs::Base
226
266
  end
227
267
  end
228
268
 
269
+ private
270
+
271
+ def enable_encoding?
272
+ @enable_encoding
273
+ end
274
+
275
+ # make sure the encoding is uniform over fields
276
+ def convert(column_name, value)
277
+ return value unless value.is_a?(String)
278
+ column_charset = @columns_charset[column_name]
279
+ if column_charset
280
+ converter = @converters[column_charset]
281
+ converter.convert(value)
282
+ elsif @charset
283
+ converter = @converters[@charset]
284
+ converter.convert(value)
285
+ else
286
+ value
287
+ end
288
+ end
229
289
  end # class LogStash::Inputs::Jdbc
@@ -40,6 +40,9 @@ module LogStash::PluginMixins::Jdbc
40
40
  # JDBC password
41
41
  config :jdbc_password, :validate => :password
42
42
 
43
+ # JDBC password filename
44
+ config :jdbc_password_filepath, :validate => :path
45
+
43
46
  # JDBC enable paging
44
47
  #
45
48
  # This will cause a sql statement to be broken up into multiple queries.
@@ -260,7 +263,6 @@ module LogStash::PluginMixins::Jdbc
260
263
 
261
264
  private
262
265
  def decorate_value(value)
263
-
264
266
  if value.is_a?(Time)
265
267
  # transform it to LogStash::Timestamp as required by LS
266
268
  LogStash::Timestamp.new(value)
@@ -269,7 +271,7 @@ module LogStash::PluginMixins::Jdbc
269
271
  # This is slower, so we put it in as a conditional case.
270
272
  LogStash::Timestamp.new(Time.parse(value.to_s))
271
273
  else
272
- value # no-op
274
+ value
273
275
  end
274
276
  end
275
277
  end
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-jdbc'
3
- s.version = '3.0.2'
3
+ s.version = '3.1.0'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "This example input streams a string at a definable interval."
6
- s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
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"
7
7
  s.authors = ["Elastic"]
8
8
  s.email = 'info@elastic.co'
9
9
  s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require "logstash/devutils/rspec/spec_helper"
2
3
  require "logstash/inputs/jdbc"
3
4
  require "jdbc/derby"
@@ -29,6 +30,7 @@ describe LogStash::Inputs::Jdbc do
29
30
  db.create_table :test_table do
30
31
  DateTime :created_at
31
32
  Integer :num
33
+ String :string
32
34
  DateTime :custom_time
33
35
  end
34
36
  end
@@ -81,6 +83,41 @@ describe LogStash::Inputs::Jdbc do
81
83
  end
82
84
  end
83
85
 
86
+ context "when both jdbc_password and jdbc_password_filepath arguments are passed" do
87
+ let(:statement) { "SELECT * from test_table" }
88
+ let(:jdbc_password) { "secret" }
89
+ let(:jdbc_password_file_path) { Stud::Temporary.pathname }
90
+ let(:settings) { { "jdbc_password_filepath" => jdbc_password_file_path,
91
+ "jdbc_password" => jdbc_password,
92
+ "statement" => statement } }
93
+
94
+ it "should fail to register" do
95
+ expect{ plugin.register }.to raise_error(LogStash::ConfigurationError)
96
+ end
97
+ end
98
+
99
+ context "when jdbc_password is passed in from a file" do
100
+ let(:statement) { "SELECT * from test_table" }
101
+ let(:jdbc_password) { "secret" }
102
+ let(:jdbc_password_file_path) { Stud::Temporary.pathname }
103
+ let(:settings) { { "jdbc_password_filepath" => jdbc_password_file_path,
104
+ "statement" => statement } }
105
+
106
+ before do
107
+ File.write(jdbc_password_file_path, jdbc_password)
108
+ plugin.register
109
+ end
110
+
111
+ after do
112
+ plugin.stop
113
+ end
114
+
115
+ it "should read in jdbc_password from file" do
116
+ expect(plugin.jdbc_password).to eq(jdbc_password)
117
+ end
118
+ end
119
+
120
+
84
121
  context "when neither statement and statement_filepath arguments are passed" do
85
122
  it "should fail to register" do
86
123
  expect{ plugin.register }.to raise_error(LogStash::ConfigurationError)
@@ -837,4 +874,109 @@ describe LogStash::Inputs::Jdbc do
837
874
  plugin.stop
838
875
  end
839
876
  end
877
+
878
+ context "when encoding of some columns need to be changed" do
879
+
880
+ let(:settings) {{ "statement" => "SELECT * from test_table" }}
881
+ let(:events) { [] }
882
+ let(:row) do
883
+ {
884
+ "column0" => "foo",
885
+ "column1" => "bar".force_encoding(Encoding::ISO_8859_1),
886
+ "column2" => 3
887
+ }
888
+ end
889
+
890
+ before(:each) do
891
+ allow_any_instance_of(Sequel::JDBC::Derby::Dataset).to receive(:each).and_yield(row)
892
+ plugin.register
893
+ end
894
+
895
+ after(:each) do
896
+ plugin.stop
897
+ end
898
+
899
+ it "should not convert any column by default" do
900
+ encoded_row = {
901
+ "column0" => "foo",
902
+ "column1" => "bar".force_encoding(Encoding::ISO_8859_1),
903
+ "column2" => 3
904
+ }
905
+ expect(LogStash::Event).to receive(:new) do |row|
906
+ row.each do |k, v|
907
+ next unless v.is_a?(String)
908
+ expect(row[k].encoding).to eq(encoded_row[k].encoding)
909
+ end
910
+ end
911
+ plugin.run(events)
912
+ end
913
+
914
+ context "when all string columns should be encoded" do
915
+
916
+ let(:settings) do
917
+ {
918
+ "statement" => "SELECT * from test_table",
919
+ "charset" => "ISO-8859-1"
920
+ }
921
+ end
922
+
923
+ let(:row) do
924
+ {
925
+ "column0" => "foo".force_encoding(Encoding::ISO_8859_1),
926
+ "column1" => "bar".force_encoding(Encoding::ISO_8859_1),
927
+ "column2" => 3
928
+ }
929
+ end
930
+
931
+ it "should transform all column string to UTF-8, default encoding" do
932
+ encoded_row = {
933
+ "column0" => "foo",
934
+ "column1" => "bar",
935
+ "column2" => 3
936
+ }
937
+ expect(LogStash::Event).to receive(:new) do |row|
938
+ row.each do |k, v|
939
+ next unless v.is_a?(String)
940
+ expect(row[k].encoding).to eq(encoded_row[k].encoding)
941
+ end
942
+ end
943
+ plugin.run(events)
944
+ end
945
+ end
946
+
947
+ context "when only an specific column should be converted" do
948
+
949
+ let(:settings) do
950
+ {
951
+ "statement" => "SELECT * from test_table",
952
+ "columns_charset" => { "column1" => "ISO-8859-1" }
953
+ }
954
+ end
955
+
956
+ let(:row) do
957
+ {
958
+ "column0" => "foo",
959
+ "column1" => "bar".force_encoding(Encoding::ISO_8859_1),
960
+ "column2" => 3,
961
+ "column3" => "berlin".force_encoding(Encoding::ASCII_8BIT)
962
+ }
963
+ end
964
+
965
+ it "should only convert the selected column" do
966
+ encoded_row = {
967
+ "column0" => "foo",
968
+ "column1" => "bar",
969
+ "column2" => 3,
970
+ "column3" => "berlin".force_encoding(Encoding::ASCII_8BIT)
971
+ }
972
+ expect(LogStash::Event).to receive(:new) do |row|
973
+ row.each do |k, v|
974
+ next unless v.is_a?(String)
975
+ expect(row[k].encoding).to eq(encoded_row[k].encoding)
976
+ end
977
+ end
978
+ plugin.run(events)
979
+ end
980
+ end
981
+ end
840
982
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-jdbc
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-24 00:00:00.000000000 Z
11
+ date: 2016-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +150,7 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
- description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
153
+ 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
154
154
  email: info@elastic.co
155
155
  executables: []
156
156
  extensions: []