embulk 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -11
  3. data/build.gradle +22 -2
  4. data/embulk-core/src/main/java/org/embulk/command/Runner.java +7 -0
  5. data/embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java +8 -6
  6. data/embulk-core/src/main/java/org/embulk/exec/LocalExecutor.java +54 -46
  7. data/embulk-core/src/main/java/org/embulk/exec/LoggerProvider.java +20 -3
  8. data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +41 -10
  9. data/embulk-core/src/main/java/org/embulk/exec/SamplingParserPlugin.java +1 -1
  10. data/embulk-core/src/main/java/org/embulk/exec/SetCurrentThreadName.java +19 -0
  11. data/embulk-core/src/main/java/org/embulk/spi/Exec.java +5 -0
  12. data/embulk-core/src/main/java/org/embulk/spi/ExecSession.java +24 -0
  13. data/embulk-core/src/main/java/org/embulk/spi/FileInputPlugin.java +4 -4
  14. data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +8 -8
  15. data/embulk-core/src/main/java/org/embulk/spi/FileOutputPlugin.java +4 -4
  16. data/embulk-core/src/main/java/org/embulk/spi/FileOutputRunner.java +8 -8
  17. data/embulk-core/src/main/java/org/embulk/spi/InputPlugin.java +4 -4
  18. data/embulk-core/src/main/java/org/embulk/spi/OutputPlugin.java +4 -4
  19. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampFormat.java +1 -1
  20. data/embulk-core/src/main/java/org/embulk/spi/util/FileOutputOutputStream.java +32 -8
  21. data/embulk-core/src/main/java/org/embulk/spi/util/InputStreamFileInput.java +1 -1
  22. data/embulk-core/src/main/java/org/embulk/spi/util/LineEncoder.java +3 -4
  23. data/embulk-core/src/main/java/org/embulk/spi/util/OutputStreamFileOutput.java +88 -0
  24. data/embulk-core/src/test/java/org/embulk/spi/TestFileInputInputStream.java +1 -1
  25. data/embulk-core/src/test/java/org/embulk/spi/TestFileInputRunner.java +5 -5
  26. data/embulk-core/src/test/java/org/embulk/spi/TestFileOutputRunner.java +4 -4
  27. data/embulk-docs/src/release.rst +1 -0
  28. data/embulk-docs/src/release/release-0.4.4.rst +39 -0
  29. data/embulk-standards/src/main/java/org/embulk/standards/GzipFileEncoderPlugin.java +32 -7
  30. data/embulk-standards/src/main/java/org/embulk/standards/LocalFileInputPlugin.java +9 -9
  31. data/embulk-standards/src/main/java/org/embulk/standards/LocalFileOutputPlugin.java +6 -6
  32. data/embulk-standards/src/main/java/org/embulk/standards/NullOutputPlugin.java +5 -5
  33. data/embulk-standards/src/main/java/org/embulk/standards/StdoutOutputPlugin.java +5 -5
  34. data/lib/embulk/command/embulk_run.rb +14 -2
  35. data/lib/embulk/data/new/java/file_input.java.erb +7 -7
  36. data/lib/embulk/data/new/java/file_output.java.erb +5 -5
  37. data/lib/embulk/data/new/java/input.java.erb +6 -6
  38. data/lib/embulk/data/new/java/output.java.erb +5 -5
  39. data/lib/embulk/data_source.rb +3 -3
  40. data/lib/embulk/guess_plugin.rb +5 -5
  41. data/lib/embulk/input_plugin.rb +7 -7
  42. data/lib/embulk/output_plugin.rb +7 -7
  43. data/lib/embulk/version.rb +1 -1
  44. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b24d1b7fd55459a318f9dbce2fff9b976f40738b
4
- data.tar.gz: 88573c322b4d3e32f4fb11775122db1c1b28f3d2
3
+ metadata.gz: 157c521d28f82705b9162cca7ca03e052d5e478f
4
+ data.tar.gz: 5063ed2e3544fede216449ea7cebc11c427faf9c
5
5
  SHA512:
6
- metadata.gz: 3179a8555d542ae38a785ad308a9b44560ae66889f263c932675e4ef5050b719636126ec0a960c6dba098030e269c3b0dd7b34f841d278857464c143ea0a2940
7
- data.tar.gz: 20772970a71e622473f119ebc4ee9316fdbfff48e96948345fb6a001342d727a70ecd525e217fac98eb0838f2e20ccebcfd6d48603c945a0d9b096f7070ea92a
6
+ metadata.gz: 694c3da663fbb60de1ac1529e9d17c561785bc0637713d3d6d325e11fdd69204e200bb359d2592b177cf5a05fb743b53d80083dfb9216807e3f1cc65a54de47b
7
+ data.tar.gz: 3b4dcaf0704cce4a6bf6af89f8e1929412b7d85c54b59d98da84efdc24ef2d55dc28f4e347fe8b15f7f887c49c77a70a405ea3777723c5b2aed7f0c0a89fb1d2
data/README.md CHANGED
@@ -24,7 +24,7 @@ You can release plugins to share your efforts of data cleaning, error handling,
24
24
  The single-file package is the simplest way to try Embulk. You can download the latest embulk-VERSION.jar from [the releases page](https://bintray.com/embulk/maven/embulk/view#files) and run it with java:
25
25
 
26
26
  ```
27
- wget https://bintray.com/artifact/download/embulk/maven/embulk-0.4.3.jar -O embulk.jar
27
+ wget https://bintray.com/artifact/download/embulk/maven/embulk-0.4.4.jar -O embulk.jar
28
28
  java -jar embulk.jar --help
29
29
  ```
30
30
 
@@ -150,20 +150,17 @@ bintray_user=(bintray user name)
150
150
  bintray_api_key=(bintray api key)
151
151
  ```
152
152
 
153
- Update following files:
153
+ Run following commands and follow its instruction:
154
154
 
155
- * embulk-docs/src/release/release-VERSION.rst (release note)
156
- * build.gradle (version number)
157
- * lib/embulk/version.rb (version number)
158
-
159
- Then, build and upload using gradle:
155
+ ```
156
+ ./gradlew set_version -Pto=$VERSION
157
+ ```
160
158
 
161
159
  ```
162
160
  ./gradlew releaseCheck
163
- ./gradlew cli gem
164
- ./gradlew bintrayUpload
165
- gem push pkg/embulk-....gem
166
- open "https://bintray.com/embulk/maven/embulk" # and upload pkg/embulk-....jar
161
+ ./gradlew release
162
+ git commit -am v$VERSION
163
+ git tag v$VERSION
167
164
  ```
168
165
 
169
166
  See also:
data/build.gradle CHANGED
@@ -11,7 +11,7 @@ def release_projects = [project(":embulk-core"), project(":embulk-standards")]
11
11
 
12
12
  allprojects {
13
13
  group = 'org.embulk'
14
- version = '0.4.3'
14
+ version = '0.4.4'
15
15
 
16
16
  apply plugin: 'java'
17
17
  apply plugin: 'maven-publish'
@@ -32,7 +32,7 @@ allprojects {
32
32
  filesSpec {
33
33
  // include embulk-<version>.jar built by 'cli' task
34
34
  from "pkg/embulk-${project.version}.jar"
35
- into "embulk-${project.version}.jar"
35
+ into "."
36
36
  }
37
37
 
38
38
  dryRun = false
@@ -229,6 +229,26 @@ Manual operations:
229
229
  bintrayUpload.mustRunAfter('releaseCheck')
230
230
  rubyGemsUpload.mustRunAfter('releaseCheck')
231
231
 
232
+ task set_version << {
233
+ if (!project.hasProperty("to")) {
234
+ throw new GradleException("Usage: ./gradlew -Pto=VERSION")
235
+ }
236
+
237
+ File gradle_ver = file('build.gradle')
238
+ gradle_ver.write(gradle_ver.getText().replaceFirst("version = '(\\d+)(\\.\\d+){2}'", "version = '${to}'"))
239
+
240
+ File ruby_ver = file('lib/embulk/version.rb')
241
+ ruby_ver.write(ruby_ver.getText().replaceFirst("VERSION = '(\\d+)(\\.\\d+){2}'", "VERSION = '${to}'"))
242
+
243
+ File readme_ver = file('README.md')
244
+ readme_ver.write(readme_ver.getText().replaceFirst('embulk-(\\d+)(\\.\\d+){2}', "embulk-${to}"))
245
+
246
+ file("embulk-docs/src/release/release-${to}.rst").append("")
247
+ "git add embulk-docs/src/release/release-${to}.rst".execute().waitFor()
248
+
249
+ println "add 'release/release-${to}' line to embulk-docs/src/release.rst"
250
+ }
251
+
232
252
  task gemspec << {
233
253
  file('build').mkdirs()
234
254
  file('build/gemspec').write($/
@@ -41,6 +41,9 @@ public class Runner
41
41
 
42
42
  private String resumeStatePath;
43
43
  public String getResumeStatePath() { return resumeStatePath; }
44
+
45
+ private String logLevel;
46
+ public String getLogLevel() { return logLevel; }
44
47
  }
45
48
 
46
49
  private final Options options;
@@ -53,6 +56,10 @@ public class Runner
53
56
  ModelManager bootstrapModelManager = new ModelManager(null, new ObjectMapper());
54
57
  this.options = bootstrapModelManager.readObject(Options.class, optionJson);
55
58
  this.systemConfig = new ConfigLoader(bootstrapModelManager).fromPropertiesYamlLiteral(System.getProperties(), "embulk.");
59
+ String logLevel = options.getLogLevel();
60
+ if (logLevel != null) {
61
+ systemConfig.set("logLevel", logLevel);
62
+ }
56
63
  this.service = new EmbulkService(systemConfig);
57
64
  this.injector = service.getInjector();
58
65
  }
@@ -70,7 +70,9 @@ public class GuessExecutor
70
70
  return Exec.doWith(exec, new ExecAction<ConfigDiff>() {
71
71
  public ConfigDiff run()
72
72
  {
73
- return doGuess(config);
73
+ try (SetCurrentThreadName dontCare = new SetCurrentThreadName("guess")) {
74
+ return doGuess(config);
75
+ }
74
76
  }
75
77
  });
76
78
  } catch (Exception ex) {
@@ -112,9 +114,9 @@ public class GuessExecutor
112
114
  ConfigDiff guessed;
113
115
  try {
114
116
  input.transaction(guessInputConfig, new InputPlugin.Control() {
115
- public List<CommitReport> run(TaskSource inputTaskSource, Schema schema, int processorCount)
117
+ public List<CommitReport> run(TaskSource inputTaskSource, Schema schema, int taskCount)
116
118
  {
117
- // TODO repeat runwith processorIndex++ if NoSampleException happens
119
+ // TODO repeat runwith taskIndex++ if NoSampleException happens
118
120
  input.run(inputTaskSource, null, 0, new PageOutput() {
119
121
  @Override
120
122
  public void add(Page page)
@@ -172,14 +174,14 @@ public class GuessExecutor
172
174
  }
173
175
 
174
176
  public ConfigDiff resume(TaskSource taskSource,
175
- int processorCount,
177
+ int taskCount,
176
178
  FileInputPlugin.Control control)
177
179
  {
178
180
  throw new UnsupportedOperationException();
179
181
  }
180
182
 
181
183
  public void cleanup(TaskSource taskSource,
182
- int processorCount,
184
+ int taskCount,
183
185
  List<CommitReport> successCommitReports)
184
186
  {
185
187
  if (buffer != null) {
@@ -188,7 +190,7 @@ public class GuessExecutor
188
190
  }
189
191
  }
190
192
 
191
- public TransactionalFileInput open(TaskSource taskSource, int processorIndex)
193
+ public TransactionalFileInput open(TaskSource taskSource, int taskIndex)
192
194
  {
193
195
  return new BufferTransactionalFileInput(buffer);
194
196
  }
@@ -95,7 +95,7 @@ public class LocalExecutor
95
95
  private volatile CommitReport[] outputCommitReports;
96
96
  private volatile ConfigDiff inputConfigDiff;
97
97
  private volatile ConfigDiff outputConfigDiff;
98
- private int processorCount;
98
+ private int taskCount;
99
99
 
100
100
  public ProcessState(Logger logger)
101
101
  {
@@ -114,7 +114,7 @@ public class LocalExecutor
114
114
  this.exceptions = new Throwable[count];
115
115
  this.inputCommitReports = new CommitReport[count];
116
116
  this.outputCommitReports = new CommitReport[count];
117
- this.processorCount = count;
117
+ this.taskCount = count;
118
118
  }
119
119
 
120
120
  public void setInputSchema(Schema inputSchema)
@@ -158,9 +158,9 @@ public class LocalExecutor
158
158
  finished[i] = true;
159
159
  }
160
160
 
161
- public int getProcessorCount()
161
+ public int getTaskCount()
162
162
  {
163
- return processorCount;
163
+ return taskCount;
164
164
  }
165
165
 
166
166
  public int getStartedCount()
@@ -209,11 +209,11 @@ public class LocalExecutor
209
209
 
210
210
  public boolean isAllCommitted()
211
211
  {
212
- if (processorCount <= 0) {
212
+ if (taskCount <= 0) {
213
213
  // not initialized
214
214
  return false;
215
215
  }
216
- for (int i=0; i < processorCount; i++) {
216
+ for (int i=0; i < taskCount; i++) {
217
217
  if (!isOutputCommitted(i)) {
218
218
  return false;
219
219
  }
@@ -223,7 +223,7 @@ public class LocalExecutor
223
223
 
224
224
  public boolean isAnyCommitted()
225
225
  {
226
- for (int i=0; i < processorCount; i++) {
226
+ for (int i=0; i < taskCount; i++) {
227
227
  if (isOutputCommitted(i)) {
228
228
  return true;
229
229
  }
@@ -355,7 +355,9 @@ public class LocalExecutor
355
355
  return Exec.doWith(exec, new ExecAction<ExecutionResult>() {
356
356
  public ExecutionResult run()
357
357
  {
358
- return doRun(config);
358
+ try (SetCurrentThreadName dontCare = new SetCurrentThreadName("transaction")) {
359
+ return doRun(config);
360
+ }
359
361
  }
360
362
  });
361
363
  } catch (Exception ex) {
@@ -370,7 +372,9 @@ public class LocalExecutor
370
372
  return Exec.doWith(exec, new ExecAction<ExecutionResult>() {
371
373
  public ExecutionResult run()
372
374
  {
373
- return doResume(config, resume);
375
+ try (SetCurrentThreadName dontCare = new SetCurrentThreadName("resume")) {
376
+ return doResume(config, resume);
377
+ }
374
378
  }
375
379
  });
376
380
  } catch (Exception ex) {
@@ -385,8 +389,10 @@ public class LocalExecutor
385
389
  Exec.doWith(exec, new ExecAction<Void>() {
386
390
  public Void run()
387
391
  {
388
- doCleanup(config, resume);
389
- return null;
392
+ try (SetCurrentThreadName dontCare = new SetCurrentThreadName("cleanup")) {
393
+ doCleanup(config, resume);
394
+ return null;
395
+ }
390
396
  }
391
397
  });
392
398
  } catch (Exception ex) {
@@ -423,24 +429,24 @@ public class LocalExecutor
423
429
  final ProcessState state = new ProcessState(Exec.getLogger(LocalExecutor.class));
424
430
  try {
425
431
  ConfigDiff inputConfigDiff = in.transaction(task.getInputConfig(), new InputPlugin.Control() {
426
- public List<CommitReport> run(final TaskSource inputTask, final Schema inputSchema, final int processorCount)
432
+ public List<CommitReport> run(final TaskSource inputTask, final Schema inputSchema, final int taskCount)
427
433
  {
428
- state.initialize(processorCount);
434
+ state.initialize(taskCount);
429
435
  state.setInputSchema(inputSchema);
430
436
  Filters.transaction(filterPlugins, task.getFilterConfigs(), inputSchema, new Filters.Control() {
431
437
  public void run(final List<TaskSource> filterTasks, final List<Schema> filterSchemas)
432
438
  {
433
439
  Schema outputSchema = last(filterSchemas);
434
440
  state.setOutputSchema(outputSchema);
435
- ConfigDiff outputConfigDiff = out.transaction(task.getOutputConfig(), outputSchema, processorCount, new OutputPlugin.Control() {
441
+ ConfigDiff outputConfigDiff = out.transaction(task.getOutputConfig(), outputSchema, taskCount, new OutputPlugin.Control() {
436
442
  public List<CommitReport> run(final TaskSource outputTask)
437
443
  {
438
444
  task.setInputTask(inputTask);
439
445
  task.setFilterTasks(filterTasks);
440
446
  task.setOutputTask(outputTask);
441
447
 
442
- if (processorCount > 0) {
443
- process(task.dump(), filterSchemas, processorCount, state);
448
+ if (taskCount > 0) {
449
+ process(task.dump(), filterSchemas, taskCount, state);
444
450
  if (!state.isAllCommitted()) {
445
451
  throw state.getRepresentativeException();
446
452
  }
@@ -489,18 +495,18 @@ public class LocalExecutor
489
495
  final ProcessState state = new ProcessState(Exec.getLogger(LocalExecutor.class));
490
496
  try {
491
497
  ConfigDiff inputConfigDiff = in.resume(resume.getInputTaskSource(), resume.getInputSchema(), resume.getInputCommitReports().size(), new InputPlugin.Control() {
492
- public List<CommitReport> run(final TaskSource inputTask, final Schema inputSchema, final int processorCount)
498
+ public List<CommitReport> run(final TaskSource inputTask, final Schema inputSchema, final int taskCount)
493
499
  {
494
500
  // TODO validate inputTask?
495
501
  // TODO validate inputSchema
496
- // TODO validate processorCount
497
- state.initialize(processorCount);
502
+ // TODO validate taskCount
503
+ state.initialize(taskCount);
498
504
  Filters.transaction(filterPlugins, task.getFilterConfigs(), inputSchema, new Filters.Control() {
499
505
  public void run(final List<TaskSource> filterTasks, final List<Schema> filterSchemas)
500
506
  {
501
507
  Schema outputSchema = last(filterSchemas);
502
508
  state.setOutputSchema(outputSchema);
503
- ConfigDiff outputConfigDiff = out.resume(resume.getOutputTaskSource(), outputSchema, processorCount, new OutputPlugin.Control() {
509
+ ConfigDiff outputConfigDiff = out.resume(resume.getOutputTaskSource(), outputSchema, taskCount, new OutputPlugin.Control() {
504
510
  public List<CommitReport> run(final TaskSource outputTask)
505
511
  {
506
512
  // TODO validate outputTask?
@@ -517,8 +523,8 @@ public class LocalExecutor
517
523
  }
518
524
  }
519
525
 
520
- if (processorCount > 0) {
521
- process(task.dump(), filterSchemas, processorCount, state);
526
+ if (taskCount > 0) {
527
+ process(task.dump(), filterSchemas, taskCount, state);
522
528
  if (!state.isAllCommitted()) {
523
529
  throw state.getRepresentativeException();
524
530
  }
@@ -556,12 +562,12 @@ public class LocalExecutor
556
562
  }
557
563
  }
558
564
 
559
- private void process(TaskSource taskSource, List<Schema> filterSchemas, int processorCount,
565
+ private void process(TaskSource taskSource, List<Schema> filterSchemas, int taskCount,
560
566
  ProcessState state)
561
567
  {
562
- List<Future<Throwable>> futures = new ArrayList<>(processorCount);
568
+ List<Future<Throwable>> futures = new ArrayList<>(taskCount);
563
569
  try {
564
- for (int i=0; i < processorCount; i++) {
570
+ for (int i=0; i < taskCount; i++) {
565
571
  if (state.isOutputCommitted(i)) {
566
572
  state.getLogger().warn("Skipped resumed task {}", i);
567
573
  futures.add(null); // resumed
@@ -571,7 +577,7 @@ public class LocalExecutor
571
577
  }
572
578
  showProgress(state);
573
579
 
574
- for (int i=0; i < processorCount; i++) {
580
+ for (int i=0; i < taskCount; i++) {
575
581
  if (futures.get(i) == null) {
576
582
  continue;
577
583
  }
@@ -597,7 +603,7 @@ public class LocalExecutor
597
603
 
598
604
  private void showProgress(ProcessState state)
599
605
  {
600
- int total = state.getProcessorCount();
606
+ int total = state.getTaskCount();
601
607
  int finished = state.getFinishedCount();
602
608
  int started = state.getStartedCount();
603
609
  state.getLogger().info(String.format("{done:%3d / %d, running: %d}", finished, total, started - finished));
@@ -610,30 +616,32 @@ public class LocalExecutor
610
616
  return executor.submit(new Callable<Throwable>() {
611
617
  public Throwable call()
612
618
  {
613
- final ExecutorTask task = taskSource.loadTask(ExecutorTask.class);
614
- final InputPlugin in = newInputPlugin(task);
615
- final List<FilterPlugin> filterPlugins = newFilterPlugins(task);
616
- final OutputPlugin out = newOutputPlugin(task);
617
-
618
- TransactionalPageOutput tran = out.open(task.getOutputTask(), last(filterSchemas), index);
619
- PageOutput closeThis = tran;
620
- state.start(index);
621
- try {
622
- PageOutput filtered = closeThis = Filters.open(filterPlugins, task.getFilterTasks(), filterSchemas, tran);
623
- state.setInputCommitReport(index, in.run(task.getInputTask(), first(filterSchemas), index, filtered));
624
- state.setOutputCommitReport(index, tran.commit()); // TODO check output.finish() is called. wrap or abstract
625
- return null;
626
- } finally {
619
+ try (SetCurrentThreadName dontCare = new SetCurrentThreadName(String.format("task-%04d", index))) {
620
+ final ExecutorTask task = taskSource.loadTask(ExecutorTask.class);
621
+ final InputPlugin in = newInputPlugin(task);
622
+ final List<FilterPlugin> filterPlugins = newFilterPlugins(task);
623
+ final OutputPlugin out = newOutputPlugin(task);
624
+
625
+ TransactionalPageOutput tran = out.open(task.getOutputTask(), last(filterSchemas), index);
626
+ PageOutput closeThis = tran;
627
+ state.start(index);
627
628
  try {
629
+ PageOutput filtered = closeThis = Filters.open(filterPlugins, task.getFilterTasks(), filterSchemas, tran);
630
+ state.setInputCommitReport(index, in.run(task.getInputTask(), first(filterSchemas), index, filtered));
631
+ state.setOutputCommitReport(index, tran.commit()); // TODO check output.finish() is called. wrap or abstract
632
+ return null;
633
+ } finally {
628
634
  try {
629
- if (!state.isOutputCommitted(index)) {
630
- tran.abort();
635
+ try {
636
+ if (!state.isOutputCommitted(index)) {
637
+ tran.abort();
638
+ }
639
+ } finally {
640
+ closeThis.close();
631
641
  }
632
642
  } finally {
633
- closeThis.close();
643
+ state.finish(index);
634
644
  }
635
- } finally {
636
- state.finish(index);
637
645
  }
638
646
  }
639
647
  }
@@ -4,20 +4,37 @@ import java.util.Properties;
4
4
  import org.slf4j.ILoggerFactory;
5
5
  import org.slf4j.LoggerFactory;
6
6
  import org.apache.log4j.PropertyConfigurator;
7
+ import com.google.inject.Inject;
7
8
  import com.google.inject.Provider;
9
+ import org.embulk.config.ConfigSource;
8
10
 
9
11
  public class LoggerProvider
10
12
  implements Provider<ILoggerFactory>
11
13
  {
12
- public LoggerProvider()
14
+ @Inject
15
+ public LoggerProvider(@ForSystemConfig ConfigSource systemConfig)
13
16
  {
14
17
  // TODO system config
15
18
  Properties prop = new Properties();
16
19
 
17
- prop.setProperty("log4j.rootLogger", "INFO,root");
20
+ final String level;
21
+ String logLevel = systemConfig.get(String.class, "logLevel", "info");
22
+ switch (logLevel) {
23
+ case "fatal": level = "FATAL"; break;
24
+ case "error": level = "ERROR"; break;
25
+ case "warn": level = "WARN"; break;
26
+ case "info": level = "INFO"; break;
27
+ case "debug": level = "DEBUG"; break;
28
+ case "trace": level = "TRACE"; break;
29
+ default:
30
+ throw new IllegalArgumentException(String.format(
31
+ "System property embulk.logLevel=%s is invalid. Available levels are fatal, error, warn, info, debug and trace.", logLevel));
32
+ }
33
+
34
+ prop.setProperty("log4j.rootLogger", level+",root");
18
35
  prop.setProperty("log4j.appender.root", "org.apache.log4j.ConsoleAppender");
19
36
  prop.setProperty("log4j.appender.root.layout", "org.apache.log4j.PatternLayout");
20
- prop.setProperty("log4j.appender.root.layout.ConversionPattern", "%d [%p]: %t:%c: %m%n");
37
+ prop.setProperty("log4j.appender.root.layout.ConversionPattern", "%d{yyyy-MM-dd HH:mm:ss.SSS Z} [%p] (%t): %m%n");
21
38
 
22
39
  // TODO
23
40
  PropertyConfigurator.configure(prop);
@@ -18,9 +18,11 @@ import org.embulk.spi.Page;
18
18
  import org.embulk.spi.PageOutput;
19
19
  import org.embulk.spi.PageReader;
20
20
  import org.embulk.spi.InputPlugin;
21
+ import org.embulk.spi.FilterPlugin;
21
22
  import org.embulk.spi.Exec;
22
23
  import org.embulk.spi.ExecSession;
23
24
  import org.embulk.spi.ExecAction;
25
+ import org.embulk.spi.util.Filters;
24
26
 
25
27
  public class PreviewExecutor
26
28
  {
@@ -34,6 +36,11 @@ public class PreviewExecutor
34
36
  @NotNull
35
37
  public ConfigSource getInputConfig();
36
38
 
39
+ @Config("filters")
40
+ @ConfigDefault("[]")
41
+ public List<ConfigSource> getFilterConfigs();
42
+
43
+ // TODO take preview_sample_rows from exec: config
37
44
  @Config("preview_sample_rows")
38
45
  @ConfigDefault("15")
39
46
  public int getSampleRows();
@@ -53,10 +60,12 @@ public class PreviewExecutor
53
60
  public PreviewResult preview(ExecSession exec, final ConfigSource config)
54
61
  {
55
62
  try {
56
- return Exec.doWith(exec, new ExecAction<PreviewResult>() {
63
+ return Exec.doWith(exec.copyForPreview(), new ExecAction<PreviewResult>() {
57
64
  public PreviewResult run()
58
65
  {
59
- return doPreview(config);
66
+ try (SetCurrentThreadName dontCare = new SetCurrentThreadName("preview")) {
67
+ return doPreview(config);
68
+ }
60
69
  }
61
70
  });
62
71
  } catch (Exception ex) {
@@ -69,19 +78,38 @@ public class PreviewExecutor
69
78
  return Exec.newPlugin(InputPlugin.class, task.getInputConfig().get(PluginType.class, "type"));
70
79
  }
71
80
 
81
+ protected List<FilterPlugin> newFilterPlugins(PreviewTask task)
82
+ {
83
+ return Filters.newFilterPlugins(Exec.session(), task.getFilterConfigs());
84
+ }
85
+
72
86
  private PreviewResult doPreview(ConfigSource config)
73
87
  {
74
88
  final PreviewTask task = config.loadConfig(PreviewTask.class);
75
- InputPlugin input = newInputPlugin(task);
89
+ final InputPlugin input = newInputPlugin(task);
90
+ final List<FilterPlugin> filterPlugins = newFilterPlugins(task);
76
91
 
77
92
  try {
78
93
  input.transaction(task.getInputConfig(), new InputPlugin.Control() {
79
- public List<CommitReport> run(TaskSource taskSource, Schema schema, int processorCount)
94
+ public List<CommitReport> run(final TaskSource inputTask, Schema inputSchema, int taskCount)
80
95
  {
81
- InputPlugin input = newInputPlugin(task);
82
- try (SamplingPageOutput out = new SamplingPageOutput(task.getSampleRows(), schema)) {
83
- input.run(taskSource, schema, 0, out);
84
- }
96
+ Filters.transaction(filterPlugins, task.getFilterConfigs(), inputSchema, new Filters.Control() {
97
+ public void run(final List<TaskSource> filterTasks, final List<Schema> filterSchemas)
98
+ {
99
+ InputPlugin input = newInputPlugin(task);
100
+ List<FilterPlugin> filterPlugins = newFilterPlugins(task);
101
+ Schema filteredSchema = filterSchemas.get(filterSchemas.size() - 1);
102
+
103
+ PageOutput out = new SamplingPageOutput(task.getSampleRows(), filteredSchema);
104
+ try {
105
+ out = Filters.open(filterPlugins, filterTasks, filterSchemas, out);
106
+ input.run(inputTask, filteredSchema, 0, out);
107
+ } finally {
108
+ out.close();
109
+ }
110
+ }
111
+ });
112
+ // program never reaches here because SamplingPageOutput.finish throws an error.
85
113
  throw new NoSampleException("No input records to preview");
86
114
  }
87
115
  });
@@ -130,8 +158,11 @@ public class PreviewExecutor
130
158
  @Override
131
159
  public void close()
132
160
  {
133
- for (Page page : pages) {
134
- page.release();
161
+ if (pages != null) {
162
+ for (Page page : pages) {
163
+ page.release();
164
+ }
165
+ pages = null;
135
166
  }
136
167
  }
137
168
  }