embulk-output-multi 0.1.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/README.md +10 -1
- data/build.gradle +1 -1
- data/gradle.properties +1 -1
- data/gradle/dependency-locks/testCompileClasspath.lockfile +1 -1
- data/src/main/java/org/embulk/output/multi/MultiOutputPlugin.java +68 -2
- data/src/test/java/org/embulk/output/multi/TestMultiOutputPlugin.java +51 -0
- data/src/test/resources/yaml/out_stop_on_failed_output.yml +9 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd9a500d9ed46b10465db1c1521c60324a90526b
|
4
|
+
data.tar.gz: fc26433a4aabf02ad3e474c503284801e816c0d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f65a6b68738a9af5638550666c3340d30f8e75fcbe7b142843a977492c98179c4d7f5c1dd875041771608e7e72c4f57113432ca55695b5f07bd378a191446cdd
|
7
|
+
data.tar.gz: 3a2cdbec13b5e9a507fc348ed69ef3270e5fbd90275e03ba1797713e12d609c489eb1dd626592d4bd13aa66879c6bc2cd771343dc292a4862557e65e7f91eb22
|
data/README.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
This plugin can copies an output to multiple destinations.
|
4
4
|
|
5
|
+
### Notes
|
6
|
+
- It's still very experimental version, so might change its configuration names or styles without notification.
|
7
|
+
- It might have performance issues or bugs when loading large records.
|
8
|
+
- It might not working on other executors than LocalExecutor.
|
9
|
+
- I would appreciate it if you use this and give me reports/feedback!
|
10
|
+
|
5
11
|
## Overview
|
6
12
|
|
7
13
|
* **Plugin type**: output
|
@@ -12,12 +18,13 @@ This plugin can copies an output to multiple destinations.
|
|
12
18
|
## Configuration
|
13
19
|
|
14
20
|
- **outputs**: Configuration of output plugins (array, required)
|
21
|
+
- **stop_on_failed_output**: Set true if you want to immediately stop outputting of all plugins with a plugin's error (boolean, default "false")
|
15
22
|
|
16
23
|
## Example
|
17
24
|
|
18
25
|
```yaml
|
19
26
|
out:
|
20
|
-
type:
|
27
|
+
type: multi
|
21
28
|
outputs:
|
22
29
|
# Output to stdout
|
23
30
|
- type: stdout
|
@@ -34,6 +41,8 @@ out:
|
|
34
41
|
formatter:
|
35
42
|
type: csv
|
36
43
|
delimiter: "\t"
|
44
|
+
# And any outputs you want..
|
45
|
+
- type: ...
|
37
46
|
```
|
38
47
|
|
39
48
|
## Build
|
data/build.gradle
CHANGED
@@ -19,7 +19,7 @@ configurations {
|
|
19
19
|
dependencies {
|
20
20
|
testImplementation "org.embulk:embulk-standards:0.9.15"
|
21
21
|
testImplementation "org.embulk:embulk-test:0.9.15"
|
22
|
-
testImplementation "com.github.kamatama41:embulk-test-helpers:0.7.
|
22
|
+
testImplementation "com.github.kamatama41:embulk-test-helpers:0.7.2"
|
23
23
|
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.2"
|
24
24
|
testImplementation "org.junit.jupiter:junit-jupiter-engine:5.3.2"
|
25
25
|
}
|
data/gradle.properties
CHANGED
@@ -1 +1 @@
|
|
1
|
-
version=0.1.
|
1
|
+
version=0.1.1
|
@@ -9,7 +9,7 @@ com.fasterxml.jackson.datatype:jackson-datatype-guava:2.6.7
|
|
9
9
|
com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.6.7
|
10
10
|
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.6.7
|
11
11
|
com.fasterxml.jackson.module:jackson-module-guice:2.6.7
|
12
|
-
com.github.kamatama41:embulk-test-helpers:0.7.
|
12
|
+
com.github.kamatama41:embulk-test-helpers:0.7.2
|
13
13
|
com.google.code.findbugs:annotations:3.0.0
|
14
14
|
com.google.guava:guava:18.0
|
15
15
|
com.google.inject.extensions:guice-multibindings:4.0
|
@@ -39,6 +39,10 @@ public class MultiOutputPlugin implements OutputPlugin {
|
|
39
39
|
@Config("outputs")
|
40
40
|
List<ConfigSource> getOutputConfigs();
|
41
41
|
|
42
|
+
@Config("stop_on_failed_output")
|
43
|
+
@ConfigDefault("false")
|
44
|
+
boolean getStopOnFailedOutput();
|
45
|
+
|
42
46
|
@Config(CONFIG_NAME_OUTPUT_CONFIG_DIFFS)
|
43
47
|
@ConfigDefault("null")
|
44
48
|
Optional<List<ConfigDiff>> getOutputConfigDiffs();
|
@@ -95,8 +99,8 @@ public class MultiOutputPlugin implements OutputPlugin {
|
|
95
99
|
public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int taskIndex) {
|
96
100
|
final PluginTask task = taskSource.loadTask(PluginTask.class);
|
97
101
|
final ExecSession session = Exec.session();
|
98
|
-
final List<
|
99
|
-
delegate.open(schema, taskIndex)
|
102
|
+
final List<TransactionalPageOutputDelegate> delegates = mapWithPluginDelegate(task, session, delegate ->
|
103
|
+
new TransactionalPageOutputDelegate(delegate, delegate.open(schema, taskIndex), task.getStopOnFailedOutput())
|
100
104
|
);
|
101
105
|
|
102
106
|
return new TransactionalPageOutput() {
|
@@ -267,6 +271,68 @@ public class MultiOutputPlugin implements OutputPlugin {
|
|
267
271
|
}
|
268
272
|
}
|
269
273
|
|
274
|
+
private static class TransactionalPageOutputDelegate implements TransactionalPageOutput {
|
275
|
+
private final OutputPluginDelegate source;
|
276
|
+
private final TransactionalPageOutput delegate;
|
277
|
+
private final boolean isStopOnFailedOutput;
|
278
|
+
|
279
|
+
TransactionalPageOutputDelegate(
|
280
|
+
OutputPluginDelegate source, TransactionalPageOutput delegate, boolean isStopOnFailedOutput) {
|
281
|
+
this.source = source;
|
282
|
+
this.delegate = delegate;
|
283
|
+
this.isStopOnFailedOutput = isStopOnFailedOutput;
|
284
|
+
}
|
285
|
+
|
286
|
+
@Override
|
287
|
+
public void add(Page page) {
|
288
|
+
try {
|
289
|
+
delegate.add(page);
|
290
|
+
} catch (Exception e) {
|
291
|
+
warnOrException(e);
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
@Override
|
296
|
+
public void finish() {
|
297
|
+
try {
|
298
|
+
delegate.finish();
|
299
|
+
} catch (Exception e) {
|
300
|
+
warnOrException(e);
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
304
|
+
@Override
|
305
|
+
public void close() {
|
306
|
+
try {
|
307
|
+
delegate.close();
|
308
|
+
} catch (Exception e) {
|
309
|
+
warnOrException(e);
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
@Override
|
314
|
+
public void abort() {
|
315
|
+
try {
|
316
|
+
delegate.abort();
|
317
|
+
} catch (Exception e) {
|
318
|
+
warnOrException(e);
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
@Override
|
323
|
+
public TaskReport commit() {
|
324
|
+
return delegate.commit();
|
325
|
+
}
|
326
|
+
|
327
|
+
private void warnOrException(Exception e) {
|
328
|
+
final String message = String.format("Failed on output for %s.", source.getPluginNameForLogging());
|
329
|
+
if (isStopOnFailedOutput) {
|
330
|
+
throw new RuntimeException(message, e);
|
331
|
+
}
|
332
|
+
LOGGER.warn(message);
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
270
336
|
private static class ControlDelegate implements OutputPlugin.Control {
|
271
337
|
private final int pluginIndex;
|
272
338
|
private final RunControlTask controlTask;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
package org.embulk.output.multi;
|
2
2
|
|
3
3
|
import org.embulk.config.ConfigSource;
|
4
|
+
import org.embulk.exec.PartialExecutionException;
|
4
5
|
import org.embulk.test.EmbulkPluginTest;
|
5
6
|
import org.embulk.test.EmbulkTest;
|
6
7
|
import org.embulk.test.Record;
|
@@ -22,6 +23,9 @@ import static org.embulk.test.LocalObjectOutputPlugin.assertRecords;
|
|
22
23
|
import static org.embulk.test.Utils.configFromResource;
|
23
24
|
import static org.embulk.test.Utils.record;
|
24
25
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
26
|
+
import static org.junit.jupiter.api.Assertions.assertNull;
|
27
|
+
import static org.junit.jupiter.api.Assertions.assertTrue;
|
28
|
+
import static org.junit.jupiter.api.Assertions.fail;
|
25
29
|
|
26
30
|
@EmbulkTest(MultiOutputPlugin.class)
|
27
31
|
class TestMultiOutputPlugin extends EmbulkPluginTest {
|
@@ -111,6 +115,53 @@ class TestMultiOutputPlugin extends EmbulkPluginTest {
|
|
111
115
|
assertRecords(records[3]);
|
112
116
|
}
|
113
117
|
|
118
|
+
@Test
|
119
|
+
void testStopOnFailedOutputIsFalse() throws IOException {
|
120
|
+
final ConfigSource inConfig = configFromResource("yaml/in_base.yml");
|
121
|
+
final ConfigSource outConfig = configFromResource("yaml/out_stop_on_failed_output.yml");
|
122
|
+
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
123
|
+
System.setOut(new PrintStream(outputStream));
|
124
|
+
|
125
|
+
// Run Embulk without error
|
126
|
+
runOutput(inConfig, outConfig);
|
127
|
+
|
128
|
+
// All records should be loaded for local_object output plugin.
|
129
|
+
final Record[] values = new Record[]{record(1, "user1", 20), record(2, "user2", 21)};
|
130
|
+
assertRecords(values);
|
131
|
+
|
132
|
+
// No record should be loaded for stdout output plugin
|
133
|
+
final BufferedReader reader = new BufferedReader(
|
134
|
+
new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray()))
|
135
|
+
);
|
136
|
+
assertNull(reader.readLine());
|
137
|
+
}
|
138
|
+
|
139
|
+
@Test
|
140
|
+
void testStopOnFailedOutputIsTrue() throws IOException {
|
141
|
+
final ConfigSource inConfig = configFromResource("yaml/in_base.yml");
|
142
|
+
final ConfigSource outConfig = configFromResource("yaml/out_stop_on_failed_output.yml")
|
143
|
+
.set("stop_on_failed_output", true);
|
144
|
+
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
145
|
+
System.setOut(new PrintStream(outputStream));
|
146
|
+
|
147
|
+
// Run Embulk
|
148
|
+
try {
|
149
|
+
runOutput(inConfig, outConfig);
|
150
|
+
fail("No exception");
|
151
|
+
} catch (PartialExecutionException e) {
|
152
|
+
assertTrue(e.getMessage().contains("Failed on output for throw_exception output plugin (pluginIndex: 0)"));
|
153
|
+
}
|
154
|
+
|
155
|
+
// No record should be loaded for local_object output plugin.
|
156
|
+
assertRecords();
|
157
|
+
|
158
|
+
// No record should be loaded for stdout output plugin
|
159
|
+
final BufferedReader reader = new BufferedReader(
|
160
|
+
new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray()))
|
161
|
+
);
|
162
|
+
assertNull(reader.readLine());
|
163
|
+
}
|
164
|
+
|
114
165
|
private static Object[][][] generateValues(int size) {
|
115
166
|
Object[][][] values = new Object[size][1][3];
|
116
167
|
for (int i = 0; i < size; i++) {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-output-multi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shinichi ISHIMURA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,7 +50,7 @@ files:
|
|
50
50
|
- LICENSE
|
51
51
|
- README.md
|
52
52
|
- build.gradle
|
53
|
-
- classpath/embulk-output-multi-0.1.
|
53
|
+
- classpath/embulk-output-multi-0.1.1.jar
|
54
54
|
- gradle.properties
|
55
55
|
- gradle/dependency-locks/compileClasspath.lockfile
|
56
56
|
- gradle/dependency-locks/testCompileClasspath.lockfile
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- src/test/java/org/embulk/output/multi/TestMultiOutputPlugin.java
|
65
65
|
- src/test/resources/yaml/in_base.yml
|
66
66
|
- src/test/resources/yaml/out_base.yml
|
67
|
+
- src/test/resources/yaml/out_stop_on_failed_output.yml
|
67
68
|
homepage: https://github.com/kamatama41/embulk-output-multi
|
68
69
|
licenses:
|
69
70
|
- MIT
|