flydata 0.6.14 → 0.7.0

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.
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