flydata 0.6.14 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/flydata-core/Gemfile +1 -0
  4. data/flydata-core/Gemfile.lock +5 -0
  5. data/flydata-core/lib/flydata-core/errors.rb +4 -2
  6. data/flydata-core/lib/flydata-core/mysql/binlog_pos.rb +4 -0
  7. data/flydata-core/lib/flydata-core/postgresql/compatibility_checker.rb +119 -0
  8. data/flydata-core/lib/flydata-core/postgresql/config.rb +58 -0
  9. data/flydata-core/lib/flydata-core/postgresql/pg_client.rb +170 -0
  10. data/flydata-core/lib/flydata-core/postgresql/snapshot.rb +49 -0
  11. data/flydata-core/lib/flydata-core/postgresql/source_pos.rb +71 -10
  12. data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +1 -1
  13. data/flydata-core/lib/flydata-core/table_def/postgresql_table_def.rb +76 -17
  14. data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +59 -10
  15. data/flydata-core/spec/mysql/binlog_pos_spec.rb +10 -2
  16. data/flydata-core/spec/postgresql/compatibility_checker_spec.rb +148 -0
  17. data/flydata-core/spec/postgresql/config_spec.rb +85 -0
  18. data/flydata-core/spec/postgresql/pg_client_spec.rb +195 -0
  19. data/flydata-core/spec/postgresql/snapshot_spec.rb +55 -0
  20. data/flydata-core/spec/postgresql/source_pos_spec.rb +70 -8
  21. data/flydata-core/spec/table_def/postgresql_table_def_spec.rb +80 -19
  22. data/flydata-core/spec/table_def/redshift_table_def_spec.rb +211 -14
  23. data/flydata.gemspec +0 -0
  24. data/lib/flydata.rb +1 -0
  25. data/lib/flydata/command/sender.rb +10 -7
  26. data/lib/flydata/command/sync.rb +4 -1
  27. data/lib/flydata/fluent-plugins/flydata_plugin_ext/base.rb +1 -0
  28. data/lib/flydata/fluent-plugins/flydata_plugin_ext/fluent_log_ext.rb +73 -0
  29. data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync.rb +35 -10
  30. data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based.rb +29 -0
  31. data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based.rb +26 -0
  32. data/lib/flydata/fluent-plugins/flydata_plugin_ext/preference.rb +29 -13
  33. data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +10 -18
  34. data/lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb +64 -0
  35. data/lib/flydata/helpers.rb +1 -3
  36. data/lib/flydata/plugin_support/context.rb +14 -2
  37. data/lib/flydata/plugin_support/source_position_file.rb +35 -0
  38. data/lib/flydata/plugin_support/sync_record_emittable.rb +2 -1
  39. data/lib/flydata/query_based_sync/client.rb +101 -0
  40. data/lib/flydata/query_based_sync/record_size_estimator.rb +39 -0
  41. data/lib/flydata/query_based_sync/resource_requester.rb +70 -0
  42. data/lib/flydata/query_based_sync/response.rb +122 -0
  43. data/lib/flydata/query_based_sync/response_handler.rb +30 -0
  44. data/lib/flydata/source/sync_generate_table_ddl.rb +1 -1
  45. data/lib/flydata/source_mysql/plugin_support/binlog_record_dispatcher.rb +2 -2
  46. data/lib/flydata/source_mysql/plugin_support/binlog_record_handler.rb +3 -9
  47. data/lib/flydata/source_mysql/plugin_support/context.rb +26 -2
  48. data/lib/flydata/source_mysql/plugin_support/source_position_file.rb +14 -0
  49. data/lib/flydata/source_mysql/table_ddl.rb +3 -3
  50. data/lib/flydata/source_mysql/{plugin_support/table_meta.rb → table_meta.rb} +3 -10
  51. data/lib/flydata/source_postgresql/generate_source_dump.rb +44 -63
  52. data/lib/flydata/source_postgresql/parse_dump_and_send.rb +2 -0
  53. data/lib/flydata/source_postgresql/plugin_support/context.rb +13 -0
  54. data/lib/flydata/source_postgresql/plugin_support/source_position_file.rb +14 -0
  55. data/lib/flydata/source_postgresql/query_based_sync/client.rb +16 -0
  56. data/lib/flydata/source_postgresql/query_based_sync/diff_query_generator.rb +135 -0
  57. data/lib/flydata/source_postgresql/query_based_sync/resource_requester.rb +86 -0
  58. data/lib/flydata/source_postgresql/query_based_sync/response.rb +12 -0
  59. data/lib/flydata/source_postgresql/query_based_sync/response_handler.rb +12 -0
  60. data/lib/flydata/source_postgresql/sync_generate_table_ddl.rb +25 -79
  61. data/lib/flydata/source_postgresql/table_meta.rb +168 -0
  62. data/lib/flydata/sync_file_manager.rb +5 -5
  63. data/lib/flydata/table_meta.rb +19 -0
  64. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_context.rb +85 -0
  65. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based_shared_examples.rb +36 -0
  66. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based_shared_examples.rb +37 -0
  67. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples.rb +67 -0
  68. data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +119 -96
  69. data/spec/flydata/fluent-plugins/in_postgresql_query_based_flydata_spec.rb +82 -0
  70. data/spec/flydata/fluent-plugins/sync_source_plugin_context.rb +29 -0
  71. data/spec/flydata/plugin_support/context_spec.rb +37 -3
  72. data/spec/flydata/query_based_sync/client_spec.rb +79 -0
  73. data/spec/flydata/query_based_sync/query_based_sync_context.rb +116 -0
  74. data/spec/flydata/query_based_sync/record_size_estimator_spec.rb +54 -0
  75. data/spec/flydata/query_based_sync/resource_requester_spec.rb +58 -0
  76. data/spec/flydata/query_based_sync/response_handler_spec.rb +36 -0
  77. data/spec/flydata/query_based_sync/response_spec.rb +157 -0
  78. data/spec/flydata/source_mysql/plugin_support/context_spec.rb +7 -1
  79. data/spec/flydata/source_mysql/plugin_support/dml_record_handler_spec.rb +2 -15
  80. data/spec/flydata/source_mysql/plugin_support/drop_database_query_handler_spec.rb +1 -1
  81. data/spec/flydata/source_mysql/plugin_support/shared_query_handler_context.rb +12 -11
  82. data/spec/flydata/source_mysql/plugin_support/source_position_file_spec.rb +53 -0
  83. data/spec/flydata/source_mysql/plugin_support/truncate_query_handler_spec.rb +1 -1
  84. data/spec/flydata/source_mysql/table_ddl_spec.rb +5 -5
  85. data/spec/flydata/source_mysql/{plugin_support/table_meta_spec.rb → table_meta_spec.rb} +6 -7
  86. data/spec/flydata/source_postgresql/generate_source_dump_spec.rb +165 -77
  87. data/spec/flydata/source_postgresql/query_based_sync/diff_query_generator_spec.rb +213 -0
  88. data/spec/flydata/source_postgresql/query_based_sync/query_based_sync_postgresql_context.rb +76 -0
  89. data/spec/flydata/source_postgresql/query_based_sync/resource_requester_spec.rb +70 -0
  90. data/spec/flydata/source_postgresql/table_meta_spec.rb +77 -0
  91. metadata +49 -6
  92. data/lib/flydata/source_mysql/plugin_support/binlog_position_file.rb +0 -23
  93. data/lib/flydata/source_postgresql/pg_client.rb +0 -43
@@ -0,0 +1,19 @@
1
+ module Flydata
2
+ class TableMeta
3
+ def initialize(opts)
4
+ @table_meta = {}
5
+ end
6
+
7
+ # Override
8
+ # Reload table meta info
9
+ #def reload(db_client)
10
+ #end
11
+
12
+ # Return table meta
13
+ # :character_set_name
14
+ def [](table_name)
15
+ @table_meta[table_name.to_sym]
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,85 @@
1
+ require 'timecop'
2
+ require 'fileutils'
3
+
4
+ module Fluent
5
+ FLYDATA_HOME = Flydata::FLYDATA_HOME
6
+ TABLE_POSITIONS_DIR = Flydata::FLYDATA_TABLE_POSITIONS_DIR
7
+ TEST_TAG = "test_tag"
8
+ TEST_DB = "test_db"
9
+ TEST_TABLE = "test_table"
10
+ TEST_SEQUENCE_FILE = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.pos")
11
+ TEST_SEQUENCE_NUM = 1
12
+ TEST_TABLE_BINLOG_POS = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.binlog.pos")
13
+ TEST_TABLES = "#{TEST_TABLE},test_table_1,test_table_2,test_table_3"
14
+ TEST_POSITION_FILE = "test_position.binlog.pos"
15
+ TEST_SENT_POSITION_FILE = "test_position.binlog.sent.pos"
16
+ TEST_REVISION_FILE = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.rev")
17
+ TEST_TIMESTAMP = 1389214083
18
+ TEST_TABLE_APPEND_ONLY = "test_table_4"
19
+ TEST_SEQUENCE_FILE_1 = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE_APPEND_ONLY}.pos")
20
+
21
+ shared_context 'flydata sync context' do
22
+ def create_file(file_path, content)
23
+ File.open(file_path, 'w') {|f| f.write(content)}
24
+ end
25
+
26
+ def delete_file(file_path)
27
+ FileUtils.rm(file_path) if File.exists?(file_path)
28
+ end
29
+
30
+ def create_binlog_pos_file(content = '')
31
+ create_file(TEST_POSITION_FILE, content)
32
+ end
33
+
34
+ def create_table_pos_file(tables, content = '')
35
+ create_table_file(tables, 'pos', content)
36
+ end
37
+
38
+ def create_table_rev_file(tables, content = '')
39
+ create_table_file(tables, 'rev', content)
40
+ end
41
+
42
+ def create_table_file(tables, ext, content = '')
43
+ tables = Array(tables)
44
+ tables.each do |table|
45
+ create_file(File.join(FLYDATA_HOME, 'positions', "#{table}.#{ext}"), content)
46
+ end
47
+ end
48
+
49
+ def config_value(variable_name, a_plugin = plugin)
50
+ a_plugin.instance_variable_get(variable_name.to_s)
51
+ end
52
+
53
+ def replace_conf(conf_str, conf_name, new_value)
54
+ if conf_str.include?(conf_name)
55
+ conf_str.gsub(/#{conf_name} .*$/, "#{conf_name} #{new_value}")
56
+ else
57
+ conf_str += "\n #{conf_name} #{new_value}\n"
58
+ end
59
+ end
60
+
61
+ def setup_initial_flydata_dirs
62
+ %w(positions dump conf).each{|f| FileUtils.mkdir_p(File.join(FLYDATA_HOME, f))}
63
+ end
64
+
65
+ def cleanup_flydata_dirs
66
+ %w(positions dump conf).each{|f| FileUtils.rm_rf(File.join(FLYDATA_HOME, f))}
67
+ end
68
+
69
+ before do
70
+ cleanup_flydata_dirs
71
+ setup_initial_flydata_dirs
72
+
73
+ @current_dir_path = Dir::pwd
74
+ Dir.chdir(FLYDATA_HOME)
75
+ create_file(TEST_POSITION_FILE, '')
76
+ end
77
+
78
+ after do
79
+ delete_file(TEST_POSITION_FILE)
80
+ Dir.chdir(@current_dir_path)
81
+
82
+ cleanup_flydata_dirs
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,36 @@
1
+ require 'flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples'
2
+
3
+
4
+ module Fluent
5
+
6
+ shared_examples 'flydata sync diff based shared examples' do
7
+ include_examples 'flydata sync shared examples'
8
+
9
+ describe '#configure' do
10
+ let(:config) do
11
+ c = default_config
12
+ c = replace_conf(c, 'tables', 'table_1')
13
+ c = replace_conf(c, 'fetch_interval', '10m')
14
+ c = replace_conf(c, 'retry_interval', '5m')
15
+ c = replace_conf(c, 'emit_chunk_limit', '32m')
16
+ c
17
+ end
18
+
19
+ subject { Test.configure_plugin(plugin, config) }
20
+
21
+ before do
22
+ create_table_pos_file('table_1')
23
+ subject
24
+ end
25
+
26
+ it { expect(config_value(:@fetch_interval)).to eq(10 * 60) }
27
+ it { expect(config_value(:@retry_interval)).to eq(5 * 60) }
28
+ it { expect(config_value(:@emit_chunk_limit)).to eq(32 * 1024**2) }
29
+ it do
30
+ expect(config_value(:@table_src_pos_files).size).to eq(1)
31
+ expect(config_value(:@table_src_pos_files)[:table_1]).to be_kind_of(described_class::SOURCE_POSITION_FILE_CLASS)
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,37 @@
1
+ require 'flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based_shared_examples'
2
+
3
+
4
+ module Fluent
5
+
6
+ shared_examples 'flydata sync query based shared examples' do
7
+ include_examples 'flydata sync diff based shared examples'
8
+
9
+ describe '#configure' do
10
+ let(:config) do
11
+ c = default_config
12
+ c = replace_conf(c, 'host', 'test-host')
13
+ c = replace_conf(c, 'port', '5555')
14
+ c = replace_conf(c, 'username', 'test-user')
15
+ c = replace_conf(c, 'password', 'test-pass')
16
+ c = replace_conf(c, 'database', 'test-db')
17
+ c = replace_conf(c, 'schema', 'test-schema')
18
+ c
19
+ end
20
+
21
+ subject { Test.configure_plugin(plugin, config) }
22
+
23
+ before do
24
+ subject
25
+ end
26
+
27
+ it { expect(config_value(:@host)).to eq('test-host') }
28
+ it { expect(config_value(:@port)).to eq(5555) }
29
+ it { expect(config_value(:@username)).to eq('test-user') }
30
+ it { expect(config_value(:@password)).to eq('test-pass') }
31
+ it { expect(config_value(:@database)).to eq('test-db') }
32
+ it { expect(config_value(:@schema)).to eq('test-schema') }
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,67 @@
1
+ require 'timecop'
2
+ require 'fileutils'
3
+ require 'flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_context'
4
+
5
+ module Fluent
6
+
7
+ # plugin and config is required
8
+ shared_examples 'flydata sync shared examples' do
9
+ include_context 'flydata sync context'
10
+
11
+ describe '#configure' do
12
+ let(:config) do
13
+ c = default_config
14
+ c = replace_conf(c, 'tables', 'table_1,table_2')
15
+ c = replace_conf(c, 'tables_append_only', 'table_3,table_4')
16
+ c
17
+ end
18
+
19
+ subject { Test.configure_plugin(plugin, config) }
20
+
21
+ before do
22
+ create_table_pos_file(%w(table_1 table_2 table_3))
23
+ create_table_rev_file('table_1', '2')
24
+ subject
25
+ end
26
+
27
+ it { expect(config_value(:@data_entry_name)).to be_kind_of(String) }
28
+ it { expect(config_value(:@data_entry_type)).to be_kind_of(String) }
29
+ it { expect(config_value(:@tag)).to be_kind_of(String) }
30
+ it { expect(config_value(:@position_file)).to be_kind_of(String) }
31
+
32
+ it 'sets @source_position_file' do
33
+ expect(config_value(:@source_position_file)).
34
+ to be_kind_of(described_class::SOURCE_POSITION_FILE_CLASS)
35
+ end
36
+
37
+ it 'sets @sent_position_file' do
38
+ expect(config_value(:@sent_position_file)).
39
+ to be_kind_of(described_class::SOURCE_POSITION_FILE_CLASS)
40
+ end
41
+
42
+ it { expect(config_value(:@data_entry)).to have_key('name') }
43
+ it { expect(config_value(:@data_entry)).to have_key('type') }
44
+ it { expect(config_value(:@tables)).to be_kind_of(Array) }
45
+
46
+ it do
47
+ expect(config_value(:@tables)).to eq(%w(table_1 table_2 table_3))
48
+ end
49
+
50
+ it do
51
+ expect(config_value(:@omit_events)).to eq(
52
+ 'table_3' => [:delete, :truncate_table],
53
+ 'table_4' => [:delete, :truncate_table],
54
+ )
55
+ end
56
+
57
+ it do
58
+ expect(config_value(:@table_revs)).to eq(
59
+ 'table_1' => 2,
60
+ 'table_2' => 1,
61
+ 'table_3' => 1,
62
+ )
63
+ end
64
+ end
65
+ end
66
+
67
+ end
@@ -2,40 +2,49 @@
2
2
 
3
3
  require 'fluent_plugins_spec_helper'
4
4
  require 'in_mysql_binlog_flydata'
5
- require 'timecop'
5
+
6
+ require 'flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples'
6
7
 
7
8
  module Fluent
8
9
 
9
- FLYDATA_HOME = Flydata::FLYDATA_HOME
10
- TEST_TAG = "test_tag"
11
- TEST_DB = "test_db"
12
- TEST_TABLE = "test_table"
13
- #TEST_SEQUENCE_FILE = /positions\/#{TEST_TABLE}.pos$/
14
- TEST_SEQUENCE_FILE = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.pos")
15
- TEST_SEQUENCE_NUM = 1
16
- TEST_TABLE_BINLOG_POS = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.binlog.pos")
17
- TEST_TABLES = "#{TEST_TABLE},test_table_1,test_table_2,test_table_3"
18
- TEST_POSITION_FILE = "test_position.binlog.pos"
19
- TEST_SENT_POSITION_FILE = "test_position.binlog.sent.pos"
20
- TEST_REVISION_FILE = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.rev")
21
- TEST_TIMESTAMP = 1389214083
22
- TEST_TABLE_APPEND_ONLY = "test_table_4"
23
- TEST_SEQUENCE_FILE_1 = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE_APPEND_ONLY}.pos")
24
- TEST_CONFIG = <<EOT
10
+ describe MysqlBinlogFlydataInput do
11
+ let(:plugin) { described_class.new }
12
+ let(:default_config) { <<EOT
13
+ data_entry_name test_name
14
+ data_entry_type RedshiftMysqlDataEntry
15
+ tag #{TEST_TAG}
16
+ database #{TEST_DB}
17
+ tables test_table,test_table_1,test_table_2
18
+ tables_append_only test_table_3
19
+ position_file #{TEST_POSITION_FILE}
20
+ host localhost
21
+ port 3306
22
+ username test_admin
23
+ password test_password
24
+ database test_db
25
+ ssl_ca_content
26
+ ssl_cipher
27
+ EOT
28
+ }
29
+ include_examples 'flydata sync shared examples'
30
+
31
+ TEST_CONFIG = <<EOT
32
+ data_entry_name test_name
33
+ data_entry_type RedshiftMysqlDataEntry
25
34
  tag #{TEST_TAG}
26
35
  database #{TEST_DB}
27
36
  tables #{TEST_TABLES}
28
37
  tables_append_only
29
38
  position_file #{TEST_POSITION_FILE}
30
39
  EOT
31
- TEST_TABLES_APPEND_ONLY_CONFIG = <<EOT
40
+ TEST_TABLES_APPEND_ONLY_CONFIG = <<EOT
32
41
  tag #{TEST_TAG}
33
42
  database #{TEST_DB}
34
43
  tables #{TEST_TABLES}
35
44
  tables_append_only #{TEST_TABLE_APPEND_ONLY}
36
45
  position_file #{TEST_POSITION_FILE}
37
46
  EOT
38
- TEST_TABLES_DUPLICATE_CONFIG = <<EOT
47
+ TEST_TABLES_DUPLICATE_CONFIG = <<EOT
39
48
  tag #{TEST_TAG}
40
49
  database #{TEST_DB}
41
50
  tables #{TEST_TABLES},#{TEST_TABLE_APPEND_ONLY}
@@ -43,105 +52,104 @@ EOT
43
52
  position_file #{TEST_POSITION_FILE}
44
53
  EOT
45
54
 
46
- # mysqlbinlog event
47
- # http://dev.mysql.com/doc/refman/5.7/en/mysqlbinlog-hexdump.html
55
+ # mysqlbinlog event
56
+ # http://dev.mysql.com/doc/refman/5.7/en/mysqlbinlog-hexdump.html
48
57
 
49
- # Supported events
50
- # - 17 WRITE_ROWS_EVENT
51
- TEST_EVENT_INSERT=<<EOT
58
+ # Supported events
59
+ # - 17 WRITE_ROWS_EVENT
60
+ TEST_EVENT_INSERT=<<EOT
52
61
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>23, "server_id"=>1, "event_length"=>39, "next_position"=>667, "flags"=>1, "event_type"=>"Write_rows", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[], "raw_used_columns"=>[255], "raw_row"=>[252, 3, 0, 0, 0, 3, 0, 102, 111, 111], "rows"=>[["1", "foo"],["2","var"],["3","hoge"]]}
53
62
  EOT
54
- TEST_EVENT_TWO_BYTE_INSERT=<<EOT
63
+ TEST_EVENT_TWO_BYTE_INSERT=<<EOT
55
64
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>23, "server_id"=>1, "event_length"=>39, "next_position"=>667, "flags"=>1, "event_type"=>"Write_rows", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[], "raw_used_columns"=>[255], "raw_row"=>[252, 3, 0, 0, 0, 3, 0, 102, 111, 111], "rows"=>[["1", "føø"],["2","vår"],["3","høgé"]]}
56
65
  EOT
57
- TEST_EVENT_THREE_BYTE_INSERT=<<EOT
66
+ TEST_EVENT_THREE_BYTE_INSERT=<<EOT
58
67
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>23, "server_id"=>1, "event_length"=>39, "next_position"=>667, "flags"=>1, "event_type"=>"Write_rows", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[], "raw_used_columns"=>[255], "raw_row"=>[252, 3, 0, 0, 0, 3, 0, 102, 111, 111], "rows"=>[["1", "富无无"],["2","易变的"],["3","切实切实"]]}
59
68
  EOT
60
- # - 18 UPDATE_ROWS_EVENT
61
- TEST_EVENT_UPDATE = <<EOT
69
+ # - 18 UPDATE_ROWS_EVENT
70
+ TEST_EVENT_UPDATE = <<EOT
62
71
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>24, "server_id"=>1, "event_length"=>78, "next_position"=>2606, "flags"=>1, "event_type"=>"Update_rows", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[255], "raw_used_columns"=>[255], "raw_row"=>[252, 6, 0, 0, 0, 1, 0, 97, 252, 6, 0, 0, 0, 1, 0, 100, 252, 6, 0, 0, 0, 1, 0, 98, 252, 6, 0, 0, 0, 1, 0, 100, 252, 6, 0, 0, 0, 1, 0, 99, 252, 6, 0, 0, 0, 1, 0, 100], "rows"=>[[["1", "foo"], ["1", "wow"]],[["3", "hoge"], ["3", "fuga"]]]}
63
72
  EOT
64
- TEST_EVENT_TWO_BYTE_UPDATE = <<EOT
73
+ TEST_EVENT_TWO_BYTE_UPDATE = <<EOT
65
74
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>24, "server_id"=>1, "event_length"=>78, "next_position"=>2606, "flags"=>1, "event_type"=>"Update_rows", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[255], "raw_used_columns"=>[255], "raw_row"=>[252, 6, 0, 0, 0, 1, 0, 97, 252, 6, 0, 0, 0, 1, 0, 100, 252, 6, 0, 0, 0, 1, 0, 98, 252, 6, 0, 0, 0, 1, 0, 100, 252, 6, 0, 0, 0, 1, 0, 99, 252, 6, 0, 0, 0, 1, 0, 100], "rows"=>[[["1", "føø"], ["1", "∑ø∑"]],[["3", "høgé"], ["3", "fügå"]]]}
66
75
  EOT
67
- TEST_EVENT_THREE_BYTE_UPDATE = <<EOT
76
+ TEST_EVENT_THREE_BYTE_UPDATE = <<EOT
68
77
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>24, "server_id"=>1, "event_length"=>78, "next_position"=>2606, "flags"=>1, "event_type"=>"Update_rows", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[255], "raw_used_columns"=>[255], "raw_row"=>[252, 6, 0, 0, 0, 1, 0, 97, 252, 6, 0, 0, 0, 1, 0, 100, 252, 6, 0, 0, 0, 1, 0, 98, 252, 6, 0, 0, 0, 1, 0, 100, 252, 6, 0, 0, 0, 1, 0, 99, 252, 6, 0, 0, 0, 1, 0, 100], "rows"=>[[["1", "富无无"], ["1", "很兴奋"]],[["3", "切实切实"], ["3", "興奮虎"]]]}
69
78
  EOT
70
- # - 19 DELETE_ROWS_EVENT
71
- TEST_EVENT_DELETE = <<EOT
79
+ # - 19 DELETE_ROWS_EVENT
80
+ TEST_EVENT_DELETE = <<EOT
72
81
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>25, "server_id"=>1, "event_length"=>41, "next_position"=>5365, "flags"=>1, "event_type"=>"Delete_rows", "table_id"=>170, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[], "raw_used_columns"=>[255], "raw_row"=>[252, 2, 0, 0, 0, 5, 0, 104, 111, 104, 111, 103], "rows"=>[["2", "var"],["3","hoge"]]}
73
82
  EOT
74
- TEST_EVENT_TWO_BYTE_DELETE = <<EOT
83
+ TEST_EVENT_TWO_BYTE_DELETE = <<EOT
75
84
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>25, "server_id"=>1, "event_length"=>41, "next_position"=>5365, "flags"=>1, "event_type"=>"Delete_rows", "table_id"=>170, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[], "raw_used_columns"=>[255], "raw_row"=>[252, 2, 0, 0, 0, 5, 0, 104, 111, 104, 111, 103], "rows"=>[["2", "vår"],["3","høgé"]]}
76
85
  EOT
77
- TEST_EVENT_THREE_BYTE_DELETE = <<EOT
86
+ TEST_EVENT_THREE_BYTE_DELETE = <<EOT
78
87
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>25, "server_id"=>1, "event_length"=>41, "next_position"=>5365, "flags"=>1, "event_type"=>"Delete_rows", "table_id"=>170, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "columns"=>["LONG", "BLOB"], "columns_len"=>2, "null_bits_len"=>1, "raw_columns_before_image"=>[], "raw_used_columns"=>[255], "raw_row"=>[252, 2, 0, 0, 0, 5, 0, 104, 111, 104, 111, 103], "rows"=>[["2", "易变的"],["3","切实切实"]]}
79
88
  EOT
80
- # Unsupported event
81
- # - 02 QUERY_EVENT
82
- # QUERY: BEGIN
83
- TEST_EVENT_QUERY_BEGIN = <<EOT
89
+ # Unsupported event
90
+ # - 02 QUERY_EVENT
91
+ # QUERY: BEGIN
92
+ TEST_EVENT_QUERY_BEGIN = <<EOT
84
93
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>73, "next_position"=>2472, "flags"=>8, "event_type"=>"Query", "thread_id"=>71, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"#{TEST_DB}", "query"=>"BEGIN"}
85
94
  EOT
86
- # QUERY: create database
87
- TEST_EVENT_QUERY_CREATE_DATABSE = <<EOT
95
+ # QUERY: create database
96
+ TEST_EVENT_QUERY_CREATE_DATABSE = <<EOT
88
97
  {"marker"=>0, "timestamp"=>1389309478, "type_code"=>2, "server_id"=>1, "event_length"=>89, "next_position"=>196, "flags"=>8, "event_type"=>"Query", "thread_id"=>39, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"test_db", "query"=>"create database test_db"}
89
98
  EOT
90
- # QUERY: create table
91
- TEST_EVENT_QUERY_CREATE_TABLE = <<EOT
99
+ # QUERY: create table
100
+ TEST_EVENT_QUERY_CREATE_TABLE = <<EOT
92
101
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>121, "next_position"=>317, "flags"=>0, "event_type"=>"Query", "thread_id"=>42, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"test_db", "query"=>"create table test_table(id int primary key, value text)"}
93
102
  EOT
94
- # QUERY: drop table
95
- TEST_EVENT_QUERY_DROP_TABLE = <<EOT
103
+ # QUERY: drop table
104
+ TEST_EVENT_QUERY_DROP_TABLE = <<EOT
96
105
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>115, "next_position"=>568, "flags"=>0, "event_type"=>"Query", "thread_id"=>42, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"test_db", "query"=>"DROP TABLE `test_table` /* generated by server */"}
97
106
  EOT
98
- # QUERY: alter table add column
99
- TEST_EVENT_QUERY_ALTER_TABLE_ADD_COLUMN = <<EOT
107
+ # QUERY: alter table add column
108
+ TEST_EVENT_QUERY_ALTER_TABLE_ADD_COLUMN = <<EOT
100
109
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>111, "next_position"=>800, "flags"=>0, "event_type"=>"Query", "thread_id"=>42, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"test_db", "query"=>"alter table test_table add column sum integer"}
101
110
  EOT
102
- # QUERY: alter table drop column
103
- TEST_EVENT_QUERY_ALTER_TABLE_DROP_COLUMN = <<EOT
111
+ # QUERY: alter table drop column
112
+ TEST_EVENT_QUERY_ALTER_TABLE_DROP_COLUMN = <<EOT
104
113
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>104, "next_position"=>904, "flags"=>0, "event_type"=>"Query", "thread_id"=>42, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"test_db", "query"=>"alter table test_table drop column sum"}
105
114
  EOT
106
- # QUERY: alter table modify column
107
- TEST_EVENT_QUERY_ALTER_TABLE_MODIFY_COLUMN = <<EOT
115
+ # QUERY: alter table modify column
116
+ TEST_EVENT_QUERY_ALTER_TABLE_MODIFY_COLUMN = <<EOT
108
117
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>112, "next_position"=>1352, "flags"=>0, "event_type"=>"Query", "thread_id"=>48, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0], "db_name"=>"test_db", "query"=>"alter table test_table modify column sum float"}
109
118
  EOT
110
- # QUERY: alter table add index
111
- TEST_EVENT_QUERY_ALTER_TABLE_ADD_INDEX = <<EOT
119
+ # QUERY: alter table add index
120
+ TEST_EVENT_QUERY_ALTER_TABLE_ADD_INDEX = <<EOT
112
121
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>217, "next_position"=>337, "flags"=>0, "event_type"=>"Query", "thread_id"=>10097, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0, 12, 1, 109, 97, 107, 95, 100, 101, 118, 101, 108, 111, 112, 109, 101, 110, 116, 0], "db_name"=>"test_db", "query"=>"ALTER TABLE `test_db`.`test_table` \nADD INDEX `my_index` USING HASH (`extra` ASC) COMMENT 'How does this look in binlog?'"}
113
122
  EOT
114
- # - 03 STOP_EVENT
115
- TEST_EVENT_STOP = <<EOT
123
+ # - 03 STOP_EVENT
124
+ TEST_EVENT_STOP = <<EOT
116
125
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>3, "server_id"=>1, "event_length"=>19, "next_position"=>2929, "flags"=>0, "event_type"=>"Stop"}
117
126
  EOT
118
- # - 04 ROTATE_EVENT
119
- TEST_EVENT_ROTATE = <<EOT
127
+ # - 04 ROTATE_EVENT
128
+ TEST_EVENT_ROTATE = <<EOT
120
129
  {"marker"=>0, "timestamp"=>0, "type_code"=>4, "server_id"=>1, "event_length"=>43, "next_position"=>0, "flags"=>32, "event_type"=>"Rotate", "binlog_file"=>"mysql-bin.000048", "binlog_pos"=>2883}
121
130
  EOT
122
- # - 0f FORMAT_DESCRIPTION_EVENT
123
- TEST_EVENT_FORMAT_DESC = <<EOT
131
+ # - 0f FORMAT_DESCRIPTION_EVENT
132
+ TEST_EVENT_FORMAT_DESC = <<EOT
124
133
  {"marker"=>0, "timestamp"=>1389292075, "type_code"=>15, "server_id"=>1, "event_length"=>103, "next_position"=>0, "flags"=>0, "event_type"=>"Format_desc", "binlog_version"=>0, "created_ts"=>2560145104, "log_header_len"=>71}
125
134
  EOT
126
- # - 10 XID_EVENT
127
- TEST_EVENT_XID = <<EOT
135
+ # - 10 XID_EVENT
136
+ TEST_EVENT_XID = <<EOT
128
137
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>16, "server_id"=>1, "event_length"=>27, "next_position"=>2633, "flags"=>0, "event_type"=>"Xid", "xid_id"=>129345}
129
138
  EOT
130
139
 
131
- # - 13 TABLE_MAP_EVENT
132
- TEST_EVENT_TABLE_MAP = <<EOT
140
+ # - 13 TABLE_MAP_EVENT
141
+ TEST_EVENT_TABLE_MAP = <<EOT
133
142
  {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>19, "server_id"=>1, "event_length"=>56, "next_position"=>2528, "flags"=>1, "event_type"=>"Table_map", "table_id"=>163, "db_name"=>"#{TEST_DB}", "table_name"=>"#{TEST_TABLE}", "raw_columns"=>[3, 252], "columns"=>["LONG", "BLOB"], "metadata"=>[2], "null_bits"=>[3]}
134
143
  EOT
135
- # la
136
- TEST_EVENT_INCIDENT = <<EOT
144
+ # la
145
+ TEST_EVENT_INCIDENT = <<EOT
137
146
  {"marker"=>0, "timestamp"=>0, "type_code"=>26, "server_id"=>1, "event_length"=>40, "next_position"=>2883, "flags"=>32, "event_type"=>"Incident", "incident_type"=>175, "message"=>"Operation canceled"}
138
147
  EOT
139
- # - 04 ROTATE_EVENT
140
- TEST_EVENT_ROTATE_MISSING_BINLOG_FILE = <<EOT
148
+ # - 04 ROTATE_EVENT
149
+ TEST_EVENT_ROTATE_MISSING_BINLOG_FILE = <<EOT
141
150
  {"marker"=>0, "timestamp"=>0, "type_code"=>4, "server_id"=>1, "event_length"=>43, "next_position"=>0, "flags"=>32, "event_type"=>"Rotate", "binlog_pos"=>2883}
142
151
  EOT
143
152
 
144
- describe MysqlBinlogFlydataInput do
145
153
  def create_event(event_str)
146
154
  event = eval(event_str)
147
155
  allow(event).to receive(:event_type).and_return(event["event_type"])
@@ -173,7 +181,6 @@ EOT
173
181
  expect_emitted_records(event, records)
174
182
  end
175
183
 
176
- let(:plugin) { MysqlBinlogFlydataInput.new }
177
184
  let(:insert_event) { create_event(TEST_EVENT_INSERT) }
178
185
  let(:insert_two_byte_event) { create_event(TEST_EVENT_TWO_BYTE_INSERT) }
179
186
  let(:insert_three_byte_event) { create_event(TEST_EVENT_THREE_BYTE_INSERT) }
@@ -196,58 +203,74 @@ EOT
196
203
  let(:now) { Time.now }
197
204
  let(:flydata_record_version) { 2 }
198
205
 
199
- let(:binlog_position_file) do
200
- f = double('binlog_position_file')
206
+ let(:source_position_file) do
207
+ f = double('source_position_file')
201
208
  allow(f).to receive(:exists?).and_return(true)
202
209
  allow(f).to receive(:read).and_return('test_position')
203
210
  f
204
211
  end
205
212
 
206
- let(:sent_position_file) do
207
- f = double('sent_position_file')
208
- allow(f).to receive(:exists?).and_return(true)
209
- allow(f).to receive(:read).and_return('test_sent_position')
210
- f
211
- end
212
-
213
- def create_file(file_path, content)
214
- File.open(file_path, 'w') {|f| f.write(content)}
215
- end
216
-
217
- def delete_file(file_path)
218
- FileUtils.rm(file_path) if File.exists?(file_path)
219
- end
220
-
221
- def setup_initial_flydata_files
222
- %w(positions dump conf).each{|f| FileUtils.mkdir_p(File.join(FLYDATA_HOME, f))}
213
+ def setup_pos_files
223
214
  create_file(TEST_SEQUENCE_FILE, TEST_SEQUENCE_NUM.to_s)
224
215
  create_file(TEST_SEQUENCE_FILE_1, TEST_SEQUENCE_NUM.to_s)
225
216
  end
226
217
 
227
- def cleanup_flydata_files
228
- %w(positions dump conf).each{|f| FileUtils.rm_rf(File.join(FLYDATA_HOME, f))}
218
+ def cleanup_pos_files
229
219
  delete_file(TEST_SEQUENCE_FILE)
230
220
  delete_file(TEST_SEQUENCE_FILE_1)
231
221
  end
232
222
 
233
223
  before do
234
- cleanup_flydata_files
235
- setup_initial_flydata_files
224
+ cleanup_pos_files
225
+ setup_pos_files
236
226
  allow(MysqlBinlogInput::BinlogUtil).to receive(:to_hash) {|e| e}
237
- allow(Flydata::SourceMysql::PluginSupport::BinLogPositionFile).to receive(:new).with(TEST_POSITION_FILE).and_return(binlog_position_file)
238
- allow(Flydata::SourceMysql::PluginSupport::BinLogPositionFile).to receive(:new).with(TEST_SENT_POSITION_FILE).
239
- and_return(sent_position_file)
240
- allow(Flydata::SourceMysql::PluginSupport::TableMeta).to receive(:update)
227
+ allow(Flydata::SourceMysql::TableMeta).to receive(:update)
241
228
  allow(plugin).to receive(:`).with("mysql -V").and_return("mysql Ver 14.14 Distrib 5.5.40")
242
229
  allow(plugin).to receive(:`).with(/^echo 'select version\(\);'/).and_return("version()\n5.5.40-0ubuntu0.12.04.1-log")
243
230
  Timecop.freeze(now)
244
231
  end
245
232
 
246
233
  after do
247
- cleanup_flydata_files
234
+ cleanup_pos_files
248
235
  Timecop.return
249
236
  end
250
237
 
238
+ describe '#configure' do
239
+ let(:config) { default_config }
240
+ before do
241
+ Test.configure_plugin(plugin, config)
242
+ end
243
+
244
+ it 'sets data entry object' do
245
+ expect(plugin.instance_variable_get(:@data_entry)).to eq(
246
+ 'name' => 'test_name',
247
+ 'type' => 'RedshiftMysqlDataEntry',
248
+ 'mysql_data_entry_preference' => {
249
+ 'database' => 'test_db',
250
+ 'tables' => 'test_table,test_table_1,test_table_2',
251
+ 'tables_append_only' => 'test_table_3',
252
+ 'host' => 'localhost',
253
+ 'username' => 'test_admin',
254
+ 'password' => 'test_password',
255
+ 'ssl_ca_content' => '',
256
+ 'ssl_cipher' => '',
257
+ }
258
+ )
259
+ end
260
+
261
+ it 'sets data tables as array' do
262
+ expect(plugin.instance_variable_get(:@tables)).to eq(%w(test_table))
263
+ end
264
+
265
+ it 'sets sync_fm' do
266
+ expect(plugin.instance_variable_get(:@sync_fm)).to be_kind_of(Flydata::SyncFileManager)
267
+ end
268
+
269
+ it 'sets omit_events' do
270
+ expect(plugin.instance_variable_get(:@omit_events)).to eq({'test_table_3' => [:delete, :truncate_table]})
271
+ end
272
+ end
273
+
251
274
  describe '#event_listener' do
252
275
 
253
276
  context 'when received rotate event' do