embulk-output-multi 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|