embulk 0.4.3 → 0.4.4

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 (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
  }