embulk 0.6.15 → 0.6.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/build.gradle +35 -1
- data/embulk-core/src/main/java/org/embulk/EmbulkService.java +2 -0
- data/embulk-core/src/main/java/org/embulk/command/Runner.java +30 -9
- data/embulk-core/src/main/java/org/embulk/exec/BulkLoader.java +7 -4
- data/embulk-core/src/main/java/org/embulk/exec/ExecModule.java +3 -0
- data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +1 -1
- data/embulk-core/src/main/java/org/embulk/exec/TempFileAllocator.java +32 -0
- data/embulk-core/src/main/java/org/embulk/{spi → plugin}/PluginClassLoader.java +34 -30
- data/embulk-core/src/main/java/org/embulk/plugin/PluginClassLoaderFactory.java +9 -0
- data/embulk-core/src/main/java/org/embulk/plugin/PluginClassLoaderModule.java +72 -0
- data/embulk-core/src/main/java/org/embulk/spi/Exec.java +6 -0
- data/embulk-core/src/main/java/org/embulk/spi/ExecSession.java +68 -26
- data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +1 -1
- data/embulk-core/src/main/java/org/embulk/spi/TaskState.java +1 -5
- data/embulk-core/src/main/java/org/embulk/spi/TempFileException.java +19 -0
- data/embulk-core/src/main/java/org/embulk/spi/TempFileSpace.java +56 -0
- data/embulk-core/src/main/java/org/embulk/spi/unit/LocalFile.java +106 -0
- data/embulk-core/src/main/java/org/embulk/spi/unit/LocalFileSerDe.java +116 -0
- data/embulk-core/src/main/java/org/embulk/spi/util/Inputs.java +0 -9
- data/embulk-core/src/main/resources/embulk/parent_first_packages.properties +70 -0
- data/embulk-core/src/main/resources/embulk/parent_first_resources.properties +28 -0
- data/embulk-core/src/test/java/org/embulk/EmbulkTestRuntime.java +3 -1
- data/embulk-docs/src/release.rst +1 -0
- data/embulk-docs/src/release/release-0.6.16.rst +26 -0
- data/lib/embulk/java/imports.rb +1 -1
- data/lib/embulk/java_plugin.rb +2 -1
- data/lib/embulk/version.rb +1 -1
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0923308ef177929c5e59513c16d318379c5d4993
|
4
|
+
data.tar.gz: ff6459b193b9635b5f666ffc3f4c878577c06e64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a5ee5b44def0c21d59f9a4ea27ba643c086626d681ad342630cd899005c05e1e1ad6fea55eb3aefd21e817cfa371156481522e59f6d5af560bfd16cab0e6f6a
|
7
|
+
data.tar.gz: cf930364ad7f307871700e9637490d3a445b1a0e78e479727828924e9e947301041c1c87834bbcb3d763e81f39afb98204c8da2fc5a2a4f7cd880b53b25c84a2
|
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.6.
|
14
|
+
version = '0.6.16'
|
15
15
|
|
16
16
|
ext {
|
17
17
|
jrubyVersion = '1.7.19'
|
@@ -149,6 +149,40 @@ dependencies {
|
|
149
149
|
jrubyExec 'rubygems:test-unit:3.0.+'
|
150
150
|
}
|
151
151
|
|
152
|
+
import java.util.zip.ZipFile
|
153
|
+
import java.util.zip.ZipEntry
|
154
|
+
task updateResources(dependsOn: 'classpath') {
|
155
|
+
doFirst {
|
156
|
+
List<String> packages = []
|
157
|
+
List<String> dirs = []
|
158
|
+
file("classpath").listFiles().each { jarFile ->
|
159
|
+
List<String> names = new ZipFile(jarFile.toString()).entries().iterator().collect { it.getName() }
|
160
|
+
packages.addAll(names.findAll { it.endsWith(".class") }.collect { it.replaceFirst(/(?:^|\/)[^\/]*\.class$/, '').replaceAll(/\//, '.') }.unique())
|
161
|
+
dirs.addAll(names.findAll { !it.endsWith("/") && !it.endsWith(".class") }.collect { it.replaceFirst(/(?:^|\/)[^\/]*$/, '') }.unique())
|
162
|
+
}
|
163
|
+
packages = packages.unique()
|
164
|
+
dirs = dirs.unique()
|
165
|
+
List<String> uniquePackages = packages.clone()
|
166
|
+
List<String> uniqueDirs = dirs.clone()
|
167
|
+
packages.each { pk -> uniquePackages.removeAll { it.startsWith(pk + '.') } }
|
168
|
+
dirs.each { dir -> uniqueDirs.removeAll { it.startsWith(dir + '/') } }
|
169
|
+
uniquePackages.removeAll { it.isEmpty() }
|
170
|
+
uniqueDirs.removeAll { it.isEmpty() || it == "META-INF" }
|
171
|
+
String date = new Date().format('yyyy-MM-dd HH:mm:ss z', TimeZone.getTimeZone("UTC"))
|
172
|
+
file("embulk-core/src/main/resources/embulk/parent_first_packages.properties").withWriter { out ->
|
173
|
+
out.println("# generated by './gradlew updateResources' at $date")
|
174
|
+
uniquePackages.sort().each { out.println it }
|
175
|
+
}
|
176
|
+
file("embulk-core/src/main/resources/embulk/parent_first_resources.properties").withWriter { out ->
|
177
|
+
out.println("# generated by './gradlew updateResources' at $date")
|
178
|
+
uniqueDirs.sort().each { out.println it }
|
179
|
+
}
|
180
|
+
}
|
181
|
+
doLast {
|
182
|
+
classpath.execute()
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
152
186
|
//
|
153
187
|
// classpath task
|
154
188
|
//
|
@@ -8,6 +8,7 @@ import org.embulk.config.ConfigSource;
|
|
8
8
|
import org.embulk.exec.SystemConfigModule;
|
9
9
|
import org.embulk.exec.ExecModule;
|
10
10
|
import org.embulk.exec.ExtensionServiceLoaderModule;
|
11
|
+
import org.embulk.plugin.PluginClassLoaderModule;
|
11
12
|
import org.embulk.plugin.BuiltinPluginSourceModule;
|
12
13
|
import org.embulk.jruby.JRubyScriptingModule;
|
13
14
|
|
@@ -21,6 +22,7 @@ public class EmbulkService
|
|
21
22
|
modules.add(new SystemConfigModule(systemConfig));
|
22
23
|
modules.add(new ExecModule());
|
23
24
|
modules.add(new ExtensionServiceLoaderModule(systemConfig));
|
25
|
+
modules.add(new PluginClassLoaderModule(systemConfig));
|
24
26
|
modules.add(new BuiltinPluginSourceModule());
|
25
27
|
modules.add(new JRubyScriptingModule(systemConfig));
|
26
28
|
modules.addAll(getAdditionalModules(systemConfig));
|
@@ -143,6 +143,7 @@ public class Runner
|
|
143
143
|
ExecutionResult result;
|
144
144
|
try {
|
145
145
|
if (resume != null) {
|
146
|
+
// exec is not used here
|
146
147
|
result = loader.resume(config, resume);
|
147
148
|
} else {
|
148
149
|
result = loader.run(exec, config);
|
@@ -156,6 +157,11 @@ public class Runner
|
|
156
157
|
} catch (Throwable ex) {
|
157
158
|
partial.addSuppressed(ex);
|
158
159
|
}
|
160
|
+
try {
|
161
|
+
exec.cleanup();
|
162
|
+
} catch (Throwable ex) {
|
163
|
+
partial.addSuppressed(ex);
|
164
|
+
}
|
159
165
|
throw partial;
|
160
166
|
}
|
161
167
|
// save the resume state
|
@@ -169,6 +175,7 @@ public class Runner
|
|
169
175
|
if (options.getResumeStatePath() != null) {
|
170
176
|
boolean dontCare = new File(options.getResumeStatePath()).delete();
|
171
177
|
}
|
178
|
+
exec.cleanup();
|
172
179
|
|
173
180
|
// write next config
|
174
181
|
ConfigDiff configDiff = result.getConfigDiff();
|
@@ -187,7 +194,6 @@ public class Runner
|
|
187
194
|
ConfigSource resumeConfig = loadYamlConfig(resumePath);
|
188
195
|
ResumeState resume = resumeConfig.loadConfig(ResumeState.class);
|
189
196
|
|
190
|
-
//ExecSession exec = newExecSession(config); // not necessary
|
191
197
|
BulkLoader loader = injector.getInstance(BulkLoader.class);
|
192
198
|
loader.cleanup(config, resume);
|
193
199
|
|
@@ -200,9 +206,16 @@ public class Runner
|
|
200
206
|
ConfigSource config = loadYamlConfig(partialConfigPath);
|
201
207
|
checkFileWritable(options.getNextConfigOutputPath());
|
202
208
|
|
203
|
-
|
204
|
-
|
205
|
-
|
209
|
+
ConfigDiff configDiff;
|
210
|
+
{
|
211
|
+
ExecSession exec = newExecSession(config);
|
212
|
+
try {
|
213
|
+
GuessExecutor guess = injector.getInstance(GuessExecutor.class);
|
214
|
+
configDiff = guess.guess(exec, config);
|
215
|
+
} finally {
|
216
|
+
exec.cleanup();
|
217
|
+
}
|
218
|
+
}
|
206
219
|
|
207
220
|
String yml = writeNextConfig(options.getNextConfigOutputPath(), config, configDiff);
|
208
221
|
System.err.println(yml);
|
@@ -244,10 +257,17 @@ public class Runner
|
|
244
257
|
|
245
258
|
public void preview(String partialConfigPath)
|
246
259
|
{
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
260
|
+
PreviewResult result;
|
261
|
+
{
|
262
|
+
ConfigSource config = loadYamlConfig(partialConfigPath);
|
263
|
+
ExecSession exec = newExecSession(config);
|
264
|
+
try {
|
265
|
+
PreviewExecutor preview = injector.getInstance(PreviewExecutor.class);
|
266
|
+
result = preview.preview(exec, config);
|
267
|
+
} finally {
|
268
|
+
exec.cleanup();
|
269
|
+
}
|
270
|
+
}
|
251
271
|
ModelManager modelManager = injector.getInstance(ModelManager.class);
|
252
272
|
|
253
273
|
PreviewPrinter printer;
|
@@ -294,7 +314,8 @@ public class Runner
|
|
294
314
|
|
295
315
|
private ExecSession newExecSession(ConfigSource config)
|
296
316
|
{
|
297
|
-
|
317
|
+
ConfigSource execConfig = config.deepCopy().getNestedOrSetEmpty("exec");
|
318
|
+
return ExecSession.builder(injector).fromExecConfig(execConfig).build();
|
298
319
|
}
|
299
320
|
|
300
321
|
private static class MapType extends HashMap<String, Object> {
|
@@ -320,7 +320,7 @@ public class BulkLoader
|
|
320
320
|
public ResumeState buildResumeState(ExecSession exec)
|
321
321
|
{
|
322
322
|
return new ResumeState(
|
323
|
-
exec.
|
323
|
+
exec.getSessionExecConfig(),
|
324
324
|
inputTaskSource, outputTaskSource,
|
325
325
|
first(schemas), executorSchema,
|
326
326
|
getInputCommitReports(), getOutputCommitReports());
|
@@ -351,8 +351,8 @@ public class BulkLoader
|
|
351
351
|
public ExecutionResult resume(final ConfigSource config, final ResumeState resume)
|
352
352
|
{
|
353
353
|
try {
|
354
|
-
ExecSession exec =
|
355
|
-
|
354
|
+
ExecSession exec = ExecSession.builder(injector).fromExecConfig(resume.getExecSessionConfigSource()).build();
|
355
|
+
ExecutionResult result = Exec.doWith(exec, new ExecAction<ExecutionResult>() {
|
356
356
|
public ExecutionResult run()
|
357
357
|
{
|
358
358
|
try (SetCurrentThreadName dontCare = new SetCurrentThreadName("resume")) {
|
@@ -360,6 +360,8 @@ public class BulkLoader
|
|
360
360
|
}
|
361
361
|
}
|
362
362
|
});
|
363
|
+
exec.cleanup();
|
364
|
+
return result;
|
363
365
|
} catch (ExecutionException ex) {
|
364
366
|
throw Throwables.propagate(ex.getCause());
|
365
367
|
}
|
@@ -368,7 +370,7 @@ public class BulkLoader
|
|
368
370
|
public void cleanup(final ConfigSource config, final ResumeState resume)
|
369
371
|
{
|
370
372
|
try {
|
371
|
-
ExecSession exec =
|
373
|
+
ExecSession exec = ExecSession.builder(injector).fromExecConfig(resume.getExecSessionConfigSource()).build();
|
372
374
|
Exec.doWith(exec, new ExecAction<Void>() {
|
373
375
|
public Void run()
|
374
376
|
{
|
@@ -378,6 +380,7 @@ public class BulkLoader
|
|
378
380
|
}
|
379
381
|
}
|
380
382
|
});
|
383
|
+
exec.cleanup();
|
381
384
|
} catch (ExecutionException ex) {
|
382
385
|
throw Throwables.propagate(ex.getCause());
|
383
386
|
}
|
@@ -16,6 +16,7 @@ import org.embulk.spi.ParserPlugin;
|
|
16
16
|
import org.embulk.spi.ExecutorPlugin;
|
17
17
|
import org.embulk.spi.BufferAllocator;
|
18
18
|
import org.embulk.spi.util.CharsetSerDe;
|
19
|
+
import org.embulk.spi.unit.LocalFileSerDe;
|
19
20
|
import static org.embulk.plugin.InjectedPluginSource.registerPluginTo;
|
20
21
|
|
21
22
|
public class ExecModule
|
@@ -29,6 +30,7 @@ public class ExecModule
|
|
29
30
|
binder.bind(ILoggerFactory.class).toProvider(LoggerProvider.class);
|
30
31
|
binder.bind(ModelManager.class).in(Scopes.SINGLETON);
|
31
32
|
binder.bind(BufferAllocator.class).to(PooledBufferAllocator.class).in(Scopes.SINGLETON);
|
33
|
+
binder.bind(TempFileAllocator.class).in(Scopes.SINGLETON);
|
32
34
|
|
33
35
|
// GuessExecutor
|
34
36
|
registerPluginTo(binder, ParserPlugin.class, "system_guess", GuessExecutor.GuessParserPlugin.class);
|
@@ -43,6 +45,7 @@ public class ExecModule
|
|
43
45
|
DateTimeZoneSerDe.configure(mapper);
|
44
46
|
TimestampSerDe.configure(mapper);
|
45
47
|
CharsetSerDe.configure(mapper);
|
48
|
+
LocalFileSerDe.configure(mapper);
|
46
49
|
mapper.registerModule(new GuavaModule()); // jackson-datatype-guava
|
47
50
|
mapper.registerModule(new JodaModule()); // jackson-datatype-joda
|
48
51
|
mapper.configure(binder);
|
@@ -60,7 +60,7 @@ public class PreviewExecutor
|
|
60
60
|
public PreviewResult preview(ExecSession exec, final ConfigSource config)
|
61
61
|
{
|
62
62
|
try {
|
63
|
-
return Exec.doWith(exec.
|
63
|
+
return Exec.doWith(exec.forPreview(), new ExecAction<PreviewResult>() {
|
64
64
|
public PreviewResult run()
|
65
65
|
{
|
66
66
|
try (SetCurrentThreadName dontCare = new SetCurrentThreadName("preview")) {
|
@@ -0,0 +1,32 @@
|
|
1
|
+
package org.embulk.exec;
|
2
|
+
|
3
|
+
import java.io.File;
|
4
|
+
import com.google.inject.Inject;
|
5
|
+
import org.embulk.config.ConfigSource;
|
6
|
+
import org.embulk.spi.TempFileSpace;
|
7
|
+
|
8
|
+
// TODO change this class to interface
|
9
|
+
// TODO don't use this class directly. Use spi.Exec.getTempFileSpace() instead.
|
10
|
+
public class TempFileAllocator
|
11
|
+
{
|
12
|
+
private final File[] dirs;
|
13
|
+
|
14
|
+
@Inject
|
15
|
+
public TempFileAllocator(@ForSystemConfig ConfigSource systemConfig)
|
16
|
+
{
|
17
|
+
// TODO get `temp_dirs` from system config
|
18
|
+
String s = System.getProperty("java.io.tmpdir");
|
19
|
+
if (s == null || s.isEmpty()) {
|
20
|
+
s = "/tmp";
|
21
|
+
}
|
22
|
+
this.dirs = new File[] {
|
23
|
+
new File(s, "embulk")
|
24
|
+
};
|
25
|
+
}
|
26
|
+
|
27
|
+
public TempFileSpace newSpace(String subdir)
|
28
|
+
{
|
29
|
+
// TODO support multiple files
|
30
|
+
return new TempFileSpace(new File(dirs[0], subdir));
|
31
|
+
}
|
32
|
+
}
|
@@ -1,6 +1,7 @@
|
|
1
|
-
package org.embulk.
|
1
|
+
package org.embulk.plugin;
|
2
2
|
|
3
3
|
import java.util.List;
|
4
|
+
import java.util.Collection;
|
4
5
|
import java.util.Iterator;
|
5
6
|
import java.util.ArrayList;
|
6
7
|
import java.util.Enumeration;
|
@@ -9,33 +10,36 @@ import java.nio.file.Path;
|
|
9
10
|
import java.net.URL;
|
10
11
|
import java.net.URLClassLoader;
|
11
12
|
import java.net.MalformedURLException;
|
13
|
+
import com.google.common.base.Function;
|
12
14
|
import com.google.common.collect.ImmutableList;
|
15
|
+
import com.google.common.collect.Iterables;
|
13
16
|
import com.google.common.collect.Iterators;
|
14
|
-
import org.jruby.Ruby;
|
15
17
|
|
16
18
|
public class PluginClassLoader
|
17
19
|
extends URLClassLoader
|
18
20
|
{
|
19
|
-
private
|
20
|
-
|
21
|
-
"org.yaml.",
|
22
|
-
"com.ibm.icu.",
|
23
|
-
};
|
24
|
-
|
25
|
-
private static final String[] CHILD_FIRST_PATHS = new String[] {
|
26
|
-
"io/netty/",
|
27
|
-
"org/yaml/",
|
28
|
-
"com/ibm/icu/",
|
29
|
-
};
|
30
|
-
|
31
|
-
public PluginClassLoader(Ruby pluginJRubyRuntime, List<URL> urls)
|
32
|
-
{
|
33
|
-
this(urls, pluginJRubyRuntime.getJRubyClassLoader());
|
34
|
-
}
|
21
|
+
private final List<String> parentFirstPackagePrefixes;
|
22
|
+
private final List<String> parentFirstResourcePrefixes;
|
35
23
|
|
36
|
-
public PluginClassLoader(
|
24
|
+
public PluginClassLoader(Collection<URL> urls, ClassLoader parent,
|
25
|
+
Collection<String> parentFirstPackages,
|
26
|
+
Collection<String> parentFirstResources)
|
37
27
|
{
|
38
28
|
super(urls.toArray(new URL[urls.size()]), parent);
|
29
|
+
this.parentFirstPackagePrefixes = ImmutableList.copyOf(
|
30
|
+
Iterables.transform(parentFirstPackages, new Function<String, String>() {
|
31
|
+
public String apply(String pkg)
|
32
|
+
{
|
33
|
+
return pkg + ".";
|
34
|
+
}
|
35
|
+
}));
|
36
|
+
this.parentFirstResourcePrefixes = ImmutableList.copyOf(
|
37
|
+
Iterables.transform(parentFirstResources, new Function<String, String>() {
|
38
|
+
public String apply(String pkg)
|
39
|
+
{
|
40
|
+
return pkg + "/";
|
41
|
+
}
|
42
|
+
}));
|
39
43
|
}
|
40
44
|
|
41
45
|
public void addPath(Path path)
|
@@ -62,8 +66,8 @@ public class PluginClassLoader
|
|
62
66
|
return resolveClass(loadedClass, resolve);
|
63
67
|
}
|
64
68
|
|
65
|
-
boolean
|
66
|
-
if (
|
69
|
+
boolean parentFirst = isParentFirstPackage(name);
|
70
|
+
if (!parentFirst) {
|
67
71
|
try {
|
68
72
|
return resolveClass(findClass(name), resolve);
|
69
73
|
} catch (ClassNotFoundException ignored) {
|
@@ -75,7 +79,7 @@ public class PluginClassLoader
|
|
75
79
|
} catch (ClassNotFoundException ignored) {
|
76
80
|
}
|
77
81
|
|
78
|
-
if (
|
82
|
+
if (parentFirst) {
|
79
83
|
return resolveClass(findClass(name), resolve);
|
80
84
|
}
|
81
85
|
|
@@ -94,7 +98,7 @@ public class PluginClassLoader
|
|
94
98
|
@Override
|
95
99
|
public URL getResource(String name)
|
96
100
|
{
|
97
|
-
boolean childFirst =
|
101
|
+
boolean childFirst = isParentFirstPath(name);
|
98
102
|
|
99
103
|
if (childFirst) {
|
100
104
|
URL childUrl = findResource(name);
|
@@ -124,9 +128,9 @@ public class PluginClassLoader
|
|
124
128
|
{
|
125
129
|
List<Iterator<URL>> resources = new ArrayList<>();
|
126
130
|
|
127
|
-
boolean
|
131
|
+
boolean parentFirst = isParentFirstPath(name);
|
128
132
|
|
129
|
-
if (
|
133
|
+
if (!parentFirst) {
|
130
134
|
Iterator<URL> childResources = Iterators.forEnumeration(findResources(name));
|
131
135
|
resources.add(childResources);
|
132
136
|
}
|
@@ -134,7 +138,7 @@ public class PluginClassLoader
|
|
134
138
|
Iterator<URL> parentResources = Iterators.forEnumeration(getParent().getResources(name));
|
135
139
|
resources.add(parentResources);
|
136
140
|
|
137
|
-
if (
|
141
|
+
if (parentFirst) {
|
138
142
|
Iterator<URL> childResources = Iterators.forEnumeration(findResources(name));
|
139
143
|
resources.add(childResources);
|
140
144
|
}
|
@@ -142,9 +146,9 @@ public class PluginClassLoader
|
|
142
146
|
return Iterators.asEnumeration(Iterators.concat(resources.iterator()));
|
143
147
|
}
|
144
148
|
|
145
|
-
private boolean
|
149
|
+
private boolean isParentFirstPackage(String name)
|
146
150
|
{
|
147
|
-
for (String pkg :
|
151
|
+
for (String pkg : parentFirstPackagePrefixes) {
|
148
152
|
if (name.startsWith(pkg)) {
|
149
153
|
return true;
|
150
154
|
}
|
@@ -152,9 +156,9 @@ public class PluginClassLoader
|
|
152
156
|
return false;
|
153
157
|
}
|
154
158
|
|
155
|
-
private boolean
|
159
|
+
private boolean isParentFirstPath(String name)
|
156
160
|
{
|
157
|
-
for (String path :
|
161
|
+
for (String path : parentFirstResourcePrefixes) {
|
158
162
|
if (name.startsWith(path)) {
|
159
163
|
return true;
|
160
164
|
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
package org.embulk.plugin;
|
2
|
+
|
3
|
+
import java.util.Collection;
|
4
|
+
import java.util.Properties;
|
5
|
+
import java.net.URL;
|
6
|
+
import java.io.InputStream;
|
7
|
+
import java.io.IOException;
|
8
|
+
import com.google.inject.Inject;
|
9
|
+
import com.google.inject.Module;
|
10
|
+
import com.google.inject.Binder;
|
11
|
+
import com.google.inject.Scopes;
|
12
|
+
import com.google.inject.Provider;
|
13
|
+
import org.embulk.config.ConfigSource;
|
14
|
+
|
15
|
+
public class PluginClassLoaderModule
|
16
|
+
implements Module
|
17
|
+
{
|
18
|
+
public PluginClassLoaderModule(ConfigSource systemConfig)
|
19
|
+
{ }
|
20
|
+
|
21
|
+
@Override
|
22
|
+
public void configure(Binder binder)
|
23
|
+
{
|
24
|
+
binder.bind(PluginClassLoaderFactory.class).toProvider(new FactoryProvider()).in(Scopes.SINGLETON);;
|
25
|
+
}
|
26
|
+
|
27
|
+
private static class FactoryProvider
|
28
|
+
implements Provider<PluginClassLoaderFactory>
|
29
|
+
{
|
30
|
+
private final Collection<String> parentFirstPackages;
|
31
|
+
private final Collection<String> parentFirstResources;
|
32
|
+
private final PluginClassLoaderFactory factory;
|
33
|
+
|
34
|
+
public FactoryProvider()
|
35
|
+
{
|
36
|
+
// TODO make these paths customizable using ConfigSource
|
37
|
+
this.parentFirstPackages = readPropertyKeys("/embulk/parent_first_packages.properties");
|
38
|
+
this.parentFirstResources = readPropertyKeys("/embulk/parent_first_resources.properties");
|
39
|
+
|
40
|
+
this.factory = new Factory();
|
41
|
+
}
|
42
|
+
|
43
|
+
private static Collection<String> readPropertyKeys(String name)
|
44
|
+
{
|
45
|
+
try (InputStream in = PluginClassLoaderModule.class.getResourceAsStream(name)) {
|
46
|
+
if (in == null) {
|
47
|
+
throw new NullPointerException(String.format("Resource '%s' is not found in classpath. Jar file or classloader is broken.", name));
|
48
|
+
}
|
49
|
+
Properties prop = new Properties();
|
50
|
+
prop.load(in);
|
51
|
+
return prop.stringPropertyNames();
|
52
|
+
} catch (IOException ex) {
|
53
|
+
throw new RuntimeException(ex);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
@Override
|
58
|
+
public PluginClassLoaderFactory get()
|
59
|
+
{
|
60
|
+
return factory;
|
61
|
+
}
|
62
|
+
|
63
|
+
private class Factory implements PluginClassLoaderFactory
|
64
|
+
{
|
65
|
+
public PluginClassLoader create(Collection<URL> urls, ClassLoader parentClassLoader)
|
66
|
+
{
|
67
|
+
return new PluginClassLoader(urls, parentClassLoader,
|
68
|
+
parentFirstPackages, parentFirstResources);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
@@ -88,6 +88,12 @@ public class Exec
|
|
88
88
|
return session().newTaskSource();
|
89
89
|
}
|
90
90
|
|
91
|
+
// TODO this method is still beta
|
92
|
+
public static TempFileSpace getTempFileSpace()
|
93
|
+
{
|
94
|
+
return session().getTempFileSpace();
|
95
|
+
}
|
96
|
+
|
91
97
|
public static boolean isPreview()
|
92
98
|
{
|
93
99
|
return session().isPreview();
|
@@ -1,5 +1,6 @@
|
|
1
1
|
package org.embulk.spi;
|
2
2
|
|
3
|
+
import java.io.File;
|
3
4
|
import org.joda.time.DateTimeZone;
|
4
5
|
import org.slf4j.Logger;
|
5
6
|
import org.slf4j.ILoggerFactory;
|
@@ -14,6 +15,7 @@ import org.embulk.config.ConfigDiff;
|
|
14
15
|
import org.embulk.config.ConfigSource;
|
15
16
|
import org.embulk.config.TaskSource;
|
16
17
|
import org.embulk.config.DataSourceImpl;
|
18
|
+
import org.embulk.exec.TempFileAllocator;
|
17
19
|
import org.embulk.plugin.PluginType;
|
18
20
|
import org.embulk.plugin.PluginManager;
|
19
21
|
import org.embulk.spi.time.Timestamp;
|
@@ -28,25 +30,67 @@ public class ExecSession
|
|
28
30
|
private final PluginManager pluginManager;
|
29
31
|
private final BufferAllocator bufferAllocator;
|
30
32
|
|
31
|
-
private final ConfigSource execConfig;
|
32
33
|
private final Timestamp transactionTime;
|
33
|
-
private final
|
34
|
+
private final TempFileSpace tempFileSpace;
|
34
35
|
|
35
36
|
private final boolean preview;
|
36
37
|
|
38
|
+
@Deprecated
|
37
39
|
public interface SessionTask
|
38
40
|
extends Task
|
39
41
|
{
|
40
42
|
@Config("transaction_time")
|
41
43
|
@ConfigDefault("null")
|
42
44
|
Optional<Timestamp> getTransactionTime();
|
45
|
+
}
|
46
|
+
|
47
|
+
public static class Builder
|
48
|
+
{
|
49
|
+
private final Injector injector;
|
50
|
+
private Timestamp transactionTime;
|
51
|
+
|
52
|
+
public Builder(Injector injector)
|
53
|
+
{
|
54
|
+
this.injector = injector;
|
55
|
+
}
|
43
56
|
|
44
|
-
|
45
|
-
|
46
|
-
|
57
|
+
public Builder fromExecConfig(ConfigSource configSource)
|
58
|
+
{
|
59
|
+
this.transactionTime = configSource.get(Timestamp.class, "transaction_time", null);
|
60
|
+
return this;
|
61
|
+
}
|
62
|
+
|
63
|
+
public Builder setTransactionTime(Timestamp timestamp)
|
64
|
+
{
|
65
|
+
this.transactionTime = timestamp;
|
66
|
+
return this;
|
67
|
+
}
|
68
|
+
|
69
|
+
public ExecSession build()
|
70
|
+
{
|
71
|
+
if (transactionTime == null) {
|
72
|
+
transactionTime = Timestamp.ofEpochMilli(System.currentTimeMillis()); // TODO get nanoseconds for default
|
73
|
+
}
|
74
|
+
return new ExecSession(injector, transactionTime);
|
75
|
+
}
|
47
76
|
}
|
48
77
|
|
49
|
-
public
|
78
|
+
public static Builder builder(Injector injector)
|
79
|
+
{
|
80
|
+
return new Builder(injector);
|
81
|
+
}
|
82
|
+
|
83
|
+
@Deprecated
|
84
|
+
public ExecSession(Injector injector, ConfigSource configSource)
|
85
|
+
{
|
86
|
+
this(injector,
|
87
|
+
configSource.loadConfig(SessionTask.class).getTransactionTime().or(
|
88
|
+
Timestamp.ofEpochMilli(System.currentTimeMillis())
|
89
|
+
)
|
90
|
+
); // TODO get nanoseconds for default
|
91
|
+
}
|
92
|
+
|
93
|
+
private ExecSession(Injector injector, Timestamp transactionTime)
|
50
94
|
{
|
51
95
|
this.injector = injector;
|
52
96
|
this.loggerFactory = injector.getInstance(ILoggerFactory.class);
|
@@ -54,10 +98,10 @@ public class ExecSession
|
|
54
98
|
this.pluginManager = injector.getInstance(PluginManager.class);
|
55
99
|
this.bufferAllocator = injector.getInstance(BufferAllocator.class);
|
56
100
|
|
57
|
-
this.
|
58
|
-
|
59
|
-
|
60
|
-
this.
|
101
|
+
this.transactionTime = transactionTime;
|
102
|
+
|
103
|
+
TempFileAllocator tempFileAllocator = injector.getInstance(TempFileAllocator.class);
|
104
|
+
this.tempFileSpace = tempFileAllocator.newSpace(transactionTime.toString());
|
61
105
|
|
62
106
|
this.preview = false;
|
63
107
|
}
|
@@ -70,23 +114,21 @@ public class ExecSession
|
|
70
114
|
this.pluginManager = copy.pluginManager;
|
71
115
|
this.bufferAllocator = copy.bufferAllocator;
|
72
116
|
|
73
|
-
this.execConfig = copy.execConfig;
|
74
117
|
this.transactionTime = copy.transactionTime;
|
75
|
-
this.
|
118
|
+
this.tempFileSpace = copy.tempFileSpace;
|
76
119
|
|
77
120
|
this.preview = preview;
|
78
121
|
}
|
79
122
|
|
80
|
-
public ExecSession
|
123
|
+
public ExecSession forPreview()
|
81
124
|
{
|
82
125
|
return new ExecSession(this, true);
|
83
126
|
}
|
84
127
|
|
85
|
-
public ConfigSource
|
128
|
+
public ConfigSource getSessionExecConfig()
|
86
129
|
{
|
87
130
|
return newConfigSource()
|
88
|
-
.set("transaction_time", transactionTime)
|
89
|
-
.set("transaction_time_zone", transactionTimeZone);
|
131
|
+
.set("transaction_time", transactionTime);
|
90
132
|
}
|
91
133
|
|
92
134
|
public Injector getInjector()
|
@@ -99,11 +141,6 @@ public class ExecSession
|
|
99
141
|
return transactionTime;
|
100
142
|
}
|
101
143
|
|
102
|
-
public DateTimeZone getTransactionTimeZone()
|
103
|
-
{
|
104
|
-
return transactionTimeZone;
|
105
|
-
}
|
106
|
-
|
107
144
|
public Logger getLogger(String name)
|
108
145
|
{
|
109
146
|
return loggerFactory.getLogger(name);
|
@@ -124,11 +161,6 @@ public class ExecSession
|
|
124
161
|
return modelManager;
|
125
162
|
}
|
126
163
|
|
127
|
-
public ConfigSource getExecConfig()
|
128
|
-
{
|
129
|
-
return execConfig;
|
130
|
-
}
|
131
|
-
|
132
164
|
public <T> T newPlugin(Class<T> iface, PluginType type)
|
133
165
|
{
|
134
166
|
return pluginManager.newPlugin(iface, type);
|
@@ -162,8 +194,18 @@ public class ExecSession
|
|
162
194
|
return new TimestampFormatter(format, formatterTask);
|
163
195
|
}
|
164
196
|
|
197
|
+
public TempFileSpace getTempFileSpace()
|
198
|
+
{
|
199
|
+
return tempFileSpace;
|
200
|
+
}
|
201
|
+
|
165
202
|
public boolean isPreview()
|
166
203
|
{
|
167
204
|
return preview;
|
168
205
|
}
|
206
|
+
|
207
|
+
public void cleanup()
|
208
|
+
{
|
209
|
+
tempFileSpace.cleanup();
|
210
|
+
}
|
169
211
|
}
|
@@ -81,7 +81,7 @@ public class FileInputRunner
|
|
81
81
|
}
|
82
82
|
|
83
83
|
GuessExecutor guessExecutor = Exec.getInjector().getInstance(GuessExecutor.class);
|
84
|
-
return guessExecutor.guessParserConfig(sample, config, Exec.session().
|
84
|
+
return guessExecutor.guessParserConfig(sample, config, Exec.session().getSessionExecConfig());
|
85
85
|
}
|
86
86
|
|
87
87
|
private class RunnerControl
|
@@ -30,11 +30,7 @@ public class TaskState
|
|
30
30
|
public void setException(Throwable exception)
|
31
31
|
{
|
32
32
|
this.started = true;
|
33
|
-
|
34
|
-
this.exception = Optional.absent();
|
35
|
-
} else {
|
36
|
-
this.exception = Optional.of(exception);
|
37
|
-
}
|
33
|
+
this.exception = Optional.fromNullable(exception);
|
38
34
|
}
|
39
35
|
|
40
36
|
public void resetException()
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package org.embulk.spi;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
|
5
|
+
public class TempFileException
|
6
|
+
extends RuntimeException
|
7
|
+
{
|
8
|
+
public TempFileException(IOException cause)
|
9
|
+
{
|
10
|
+
super(cause);
|
11
|
+
}
|
12
|
+
|
13
|
+
|
14
|
+
@Override
|
15
|
+
public IOException getCause()
|
16
|
+
{
|
17
|
+
return (IOException) super.getCause();
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
package org.embulk.spi;
|
2
|
+
|
3
|
+
import java.util.List;
|
4
|
+
import java.util.ArrayList;
|
5
|
+
import java.util.Collections;
|
6
|
+
import java.io.File;
|
7
|
+
import java.io.IOException;
|
8
|
+
import com.google.common.base.Preconditions;
|
9
|
+
|
10
|
+
public class TempFileSpace
|
11
|
+
{
|
12
|
+
private final File dir;
|
13
|
+
private boolean dirCreated;
|
14
|
+
|
15
|
+
public TempFileSpace(File dir)
|
16
|
+
{
|
17
|
+
Preconditions.checkArgument(dir != null, "dir is null");
|
18
|
+
this.dir = dir;
|
19
|
+
}
|
20
|
+
|
21
|
+
public File createTempFile()
|
22
|
+
{
|
23
|
+
return createTempFile("tmp");
|
24
|
+
}
|
25
|
+
|
26
|
+
public File createTempFile(String fileExt)
|
27
|
+
{
|
28
|
+
return createTempFile(Thread.currentThread().getName()+"_", fileExt);
|
29
|
+
}
|
30
|
+
|
31
|
+
public File createTempFile(String prefix, String fileExt)
|
32
|
+
{
|
33
|
+
try {
|
34
|
+
if (!dirCreated) {
|
35
|
+
dir.mkdirs();
|
36
|
+
dirCreated = true;
|
37
|
+
}
|
38
|
+
return File.createTempFile(prefix, "."+fileExt, dir);
|
39
|
+
} catch (IOException ex) {
|
40
|
+
throw new TempFileException(ex);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
public void cleanup()
|
45
|
+
{
|
46
|
+
File[] files = dir.listFiles();
|
47
|
+
if (files != null) {
|
48
|
+
for (File e : files) {
|
49
|
+
e.delete();
|
50
|
+
// TODO delete directory recursively
|
51
|
+
}
|
52
|
+
}
|
53
|
+
dir.delete();
|
54
|
+
dirCreated = false;
|
55
|
+
}
|
56
|
+
}
|
@@ -0,0 +1,106 @@
|
|
1
|
+
package org.embulk.spi.unit;
|
2
|
+
|
3
|
+
import java.io.File;
|
4
|
+
import java.io.IOException;
|
5
|
+
import java.io.InputStream;
|
6
|
+
import java.io.ByteArrayInputStream;
|
7
|
+
import java.nio.file.Path;
|
8
|
+
import java.nio.file.Paths;
|
9
|
+
import java.nio.file.Files;
|
10
|
+
import java.nio.charset.Charset;
|
11
|
+
import java.nio.charset.StandardCharsets;
|
12
|
+
import org.embulk.spi.Exec;
|
13
|
+
import org.embulk.spi.TempFileSpace;
|
14
|
+
import org.embulk.spi.TempFileException;
|
15
|
+
|
16
|
+
public class LocalFile
|
17
|
+
{
|
18
|
+
public static LocalFile of(File path) throws IOException
|
19
|
+
{
|
20
|
+
return of(path.toPath());
|
21
|
+
}
|
22
|
+
|
23
|
+
public static LocalFile of(Path path) throws IOException
|
24
|
+
{
|
25
|
+
return new LocalFile(path, Files.readAllBytes(path));
|
26
|
+
}
|
27
|
+
|
28
|
+
public static LocalFile of(String path) throws IOException
|
29
|
+
{
|
30
|
+
return of(Paths.get(path));
|
31
|
+
}
|
32
|
+
|
33
|
+
public static LocalFile ofContent(byte[] content)
|
34
|
+
{
|
35
|
+
return new LocalFile(content);
|
36
|
+
}
|
37
|
+
|
38
|
+
public static LocalFile ofContent(String content)
|
39
|
+
{
|
40
|
+
return new LocalFile(content.getBytes(StandardCharsets.UTF_8));
|
41
|
+
}
|
42
|
+
|
43
|
+
private Path path;
|
44
|
+
private final byte[] content;
|
45
|
+
|
46
|
+
private LocalFile(Path path, byte[] content)
|
47
|
+
{
|
48
|
+
this.path = path;
|
49
|
+
this.content = content;
|
50
|
+
}
|
51
|
+
|
52
|
+
private LocalFile(byte[] content)
|
53
|
+
{
|
54
|
+
this.path = null;
|
55
|
+
this.content = content;
|
56
|
+
}
|
57
|
+
|
58
|
+
public File getFile()
|
59
|
+
{
|
60
|
+
return getPath(Exec.getTempFileSpace()).toFile();
|
61
|
+
}
|
62
|
+
|
63
|
+
public File getFile(TempFileSpace space)
|
64
|
+
{
|
65
|
+
return getPath(space).toFile();
|
66
|
+
}
|
67
|
+
|
68
|
+
public Path getPath()
|
69
|
+
{
|
70
|
+
return getPath(Exec.getTempFileSpace());
|
71
|
+
}
|
72
|
+
|
73
|
+
public synchronized Path getPath(TempFileSpace tempFileSpace)
|
74
|
+
{
|
75
|
+
if (path == null) {
|
76
|
+
Path temp = tempFileSpace.createTempFile().toPath();
|
77
|
+
try {
|
78
|
+
Files.write(temp, content);
|
79
|
+
} catch (IOException ex) {
|
80
|
+
throw new TempFileException(ex);
|
81
|
+
}
|
82
|
+
this.path = temp;
|
83
|
+
}
|
84
|
+
return path;
|
85
|
+
}
|
86
|
+
|
87
|
+
public byte[] getContent()
|
88
|
+
{
|
89
|
+
return content;
|
90
|
+
}
|
91
|
+
|
92
|
+
public String getContentAsString()
|
93
|
+
{
|
94
|
+
return new String(content);
|
95
|
+
}
|
96
|
+
|
97
|
+
public String getContentAsString(Charset charset)
|
98
|
+
{
|
99
|
+
return new String(content, charset);
|
100
|
+
}
|
101
|
+
|
102
|
+
public InputStream newContentInputStream()
|
103
|
+
{
|
104
|
+
return new ByteArrayInputStream(content);
|
105
|
+
}
|
106
|
+
}
|
@@ -0,0 +1,116 @@
|
|
1
|
+
package org.embulk.spi.unit;
|
2
|
+
|
3
|
+
import java.io.File;
|
4
|
+
import java.io.ByteArrayOutputStream;
|
5
|
+
import java.io.IOException;
|
6
|
+
import com.fasterxml.jackson.core.JsonGenerator;
|
7
|
+
import com.fasterxml.jackson.core.JsonParser;
|
8
|
+
import com.fasterxml.jackson.core.JsonToken;
|
9
|
+
import com.fasterxml.jackson.databind.module.SimpleModule;
|
10
|
+
import com.fasterxml.jackson.databind.JsonSerializer;
|
11
|
+
import com.fasterxml.jackson.databind.JsonDeserializer;
|
12
|
+
import com.fasterxml.jackson.databind.SerializerProvider;
|
13
|
+
import com.fasterxml.jackson.databind.DeserializationContext;
|
14
|
+
import com.fasterxml.jackson.databind.JsonNode;
|
15
|
+
import com.fasterxml.jackson.databind.JsonMappingException;
|
16
|
+
import com.fasterxml.jackson.databind.node.ObjectNode;
|
17
|
+
import com.fasterxml.jackson.module.guice.ObjectMapperModule;
|
18
|
+
|
19
|
+
public class LocalFileSerDe
|
20
|
+
{
|
21
|
+
public static void configure(ObjectMapperModule mapper)
|
22
|
+
{
|
23
|
+
SimpleModule module = new SimpleModule();
|
24
|
+
module.addSerializer(LocalFile.class, new LocalFileSerializer());
|
25
|
+
module.addDeserializer(LocalFile.class, new LocalFileDeserializer());
|
26
|
+
mapper.registerModule(module);
|
27
|
+
}
|
28
|
+
|
29
|
+
private static class LocalFileSerializer
|
30
|
+
extends JsonSerializer<LocalFile>
|
31
|
+
{
|
32
|
+
@Override
|
33
|
+
public void serialize(LocalFile value, JsonGenerator jgen, SerializerProvider provider)
|
34
|
+
throws IOException
|
35
|
+
{
|
36
|
+
jgen.writeStartObject();
|
37
|
+
jgen.writeFieldName("base64");
|
38
|
+
jgen.writeBinary(value.getContent());
|
39
|
+
jgen.writeEndObject();
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
private static class LocalFileDeserializer
|
44
|
+
extends JsonDeserializer<LocalFile>
|
45
|
+
{
|
46
|
+
private final File tempDir;
|
47
|
+
|
48
|
+
public LocalFileDeserializer()
|
49
|
+
{
|
50
|
+
this(new File(System.getProperty("java.io.tmpdir")));
|
51
|
+
}
|
52
|
+
|
53
|
+
public LocalFileDeserializer(File tempDir)
|
54
|
+
{
|
55
|
+
this.tempDir = tempDir;
|
56
|
+
}
|
57
|
+
|
58
|
+
@Override
|
59
|
+
public LocalFile deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
|
60
|
+
{
|
61
|
+
JsonToken t = jp.getCurrentToken();
|
62
|
+
if (t == JsonToken.START_OBJECT) {
|
63
|
+
t = jp.nextToken();
|
64
|
+
}
|
65
|
+
|
66
|
+
switch(t) {
|
67
|
+
case VALUE_NULL:
|
68
|
+
return null;
|
69
|
+
|
70
|
+
case FIELD_NAME:
|
71
|
+
{
|
72
|
+
LocalFile result;
|
73
|
+
|
74
|
+
String keyName = jp.getCurrentName();
|
75
|
+
if ("content".equals(keyName)) {
|
76
|
+
jp.nextToken();
|
77
|
+
result = LocalFile.ofContent(jp.getValueAsString());
|
78
|
+
} else if ("base64".equals(keyName)) {
|
79
|
+
jp.nextToken();
|
80
|
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
81
|
+
jp.readBinaryValue(ctxt.getBase64Variant(), out);
|
82
|
+
result = LocalFile.ofContent(out.toByteArray());
|
83
|
+
} else {
|
84
|
+
throw ctxt.mappingException("Unknown key '"+keyName+"' to deserialize LocalFile");
|
85
|
+
}
|
86
|
+
|
87
|
+
t = jp.nextToken();
|
88
|
+
if (t != JsonToken.END_OBJECT) {
|
89
|
+
throw ctxt.mappingException("Unexpected extra map keys to LocalFile");
|
90
|
+
}
|
91
|
+
return result;
|
92
|
+
}
|
93
|
+
|
94
|
+
case END_OBJECT:
|
95
|
+
case START_ARRAY:
|
96
|
+
case END_ARRAY:
|
97
|
+
throw ctxt.mappingException("Attempted unexpected map or array to LocalFile");
|
98
|
+
|
99
|
+
case VALUE_EMBEDDED_OBJECT:
|
100
|
+
{
|
101
|
+
Object obj = jp.getEmbeddedObject();
|
102
|
+
if (obj == null) {
|
103
|
+
return null;
|
104
|
+
}
|
105
|
+
if (LocalFile.class.isAssignableFrom(obj.getClass())) {
|
106
|
+
return (LocalFile) obj;
|
107
|
+
}
|
108
|
+
throw ctxt.mappingException("Don't know how to convert embedded Object of type "+obj.getClass().getName()+" into LocalFile");
|
109
|
+
}
|
110
|
+
|
111
|
+
default:
|
112
|
+
return LocalFile.of(jp.getValueAsString());
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
@@ -62,13 +62,4 @@ public class Inputs
|
|
62
62
|
}
|
63
63
|
};
|
64
64
|
}
|
65
|
-
|
66
|
-
public static String formatPath(String pathFormat)
|
67
|
-
{
|
68
|
-
Timestamp timestamp = Exec.session().getTransactionTime();
|
69
|
-
DateTimeZone timezone = Exec.session().getTransactionTimeZone();
|
70
|
-
// newTimestampFormatter (eventually calls org.jruby.util.RubyDateFormat.<init> doesn't throw exceptions
|
71
|
-
TimestampFormatter formatter = Exec.session().newTimestampFormatter(pathFormat, timezone);
|
72
|
-
return formatter.format(timestamp); // TimestampFormatter.format doesn't throw exceptions
|
73
|
-
}
|
74
65
|
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# generated by './gradlew updateResources' at 2015-06-30 23:52:09 UTC
|
2
|
+
ch.qos.logback.classic
|
3
|
+
ch.qos.logback.core
|
4
|
+
com.fasterxml.jackson.annotation
|
5
|
+
com.fasterxml.jackson.core
|
6
|
+
com.fasterxml.jackson.databind
|
7
|
+
com.fasterxml.jackson.datatype.guava
|
8
|
+
com.fasterxml.jackson.datatype.joda
|
9
|
+
com.fasterxml.jackson.module.guice
|
10
|
+
com.google.common.annotations
|
11
|
+
com.google.common.base
|
12
|
+
com.google.common.cache
|
13
|
+
com.google.common.collect
|
14
|
+
com.google.common.escape
|
15
|
+
com.google.common.eventbus
|
16
|
+
com.google.common.hash
|
17
|
+
com.google.common.html
|
18
|
+
com.google.common.io
|
19
|
+
com.google.common.math
|
20
|
+
com.google.common.net
|
21
|
+
com.google.common.primitives
|
22
|
+
com.google.common.reflect
|
23
|
+
com.google.common.util.concurrent
|
24
|
+
com.google.common.xml
|
25
|
+
com.google.inject
|
26
|
+
com.google.thirdparty.publicsuffix
|
27
|
+
com.headius.invokebinder
|
28
|
+
com.headius.options
|
29
|
+
com.ibm.icu.impl
|
30
|
+
com.ibm.icu.lang
|
31
|
+
com.ibm.icu.math
|
32
|
+
com.ibm.icu.text
|
33
|
+
com.ibm.icu.util
|
34
|
+
com.jcraft.jzlib
|
35
|
+
com.kenai.constantine
|
36
|
+
com.kenai.jffi
|
37
|
+
com.kenai.jnr.x86asm
|
38
|
+
com.martiansoftware.nailgun
|
39
|
+
edu.umd.cs.findbugs.annotations
|
40
|
+
io.airlift.slice
|
41
|
+
io.netty.buffer
|
42
|
+
io.netty.util
|
43
|
+
javax.annotation
|
44
|
+
javax.inject
|
45
|
+
javax.validation
|
46
|
+
jnr.constants
|
47
|
+
jnr.enxio.channels
|
48
|
+
jnr.enxio.example
|
49
|
+
jnr.ffi
|
50
|
+
jnr.netdb
|
51
|
+
jnr.posix
|
52
|
+
jnr.unixsocket
|
53
|
+
jnr.x86asm
|
54
|
+
net.jcip.annotations
|
55
|
+
org.aopalliance.aop
|
56
|
+
org.aopalliance.intercept
|
57
|
+
org.apache.bval
|
58
|
+
org.apache.commons.beanutils
|
59
|
+
org.apache.commons.collections
|
60
|
+
org.apache.commons.lang3
|
61
|
+
org.embulk
|
62
|
+
org.fusesource.hawtjni.runtime
|
63
|
+
org.fusesource.jansi
|
64
|
+
org.jcodings
|
65
|
+
org.joda.time
|
66
|
+
org.joni
|
67
|
+
org.jruby
|
68
|
+
org.slf4j
|
69
|
+
org.yaml.snakeyaml
|
70
|
+
org.yecht
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# generated by './gradlew updateResources' at 2015-06-30 23:52:09 UTC
|
2
|
+
ch/qos/logback/classic/boolex
|
3
|
+
ch/qos/logback/classic/db/script
|
4
|
+
com/ibm/icu
|
5
|
+
com/martiansoftware/nailgun/builtins
|
6
|
+
edu/umd/cs/findbugs/annotations
|
7
|
+
embulk
|
8
|
+
javax/annotation
|
9
|
+
jni/Darwin
|
10
|
+
jni/arm-Linux
|
11
|
+
jni/i386-Linux
|
12
|
+
jni/i386-SunOS
|
13
|
+
jni/i386-Windows
|
14
|
+
jni/ppc-AIX
|
15
|
+
jni/sparcv9-SunOS
|
16
|
+
jni/x86_64-FreeBSD
|
17
|
+
jni/x86_64-Linux
|
18
|
+
jni/x86_64-SunOS
|
19
|
+
jni/x86_64-Windows
|
20
|
+
jruby
|
21
|
+
net/jcip/annotations
|
22
|
+
okay
|
23
|
+
org/apache/bval/jsr303
|
24
|
+
org/joda/time/format
|
25
|
+
org/joda/time/tz/data
|
26
|
+
tables
|
27
|
+
templates
|
28
|
+
yaml
|
@@ -52,7 +52,7 @@ public class EmbulkTestRuntime
|
|
52
52
|
super(new TestRuntimeModule());
|
53
53
|
Injector injector = getInjector();
|
54
54
|
ConfigSource execConfig = new DataSourceImpl(injector.getInstance(ModelManager.class));
|
55
|
-
this.exec =
|
55
|
+
this.exec = ExecSession.builder(injector).fromExecConfig(execConfig).build();
|
56
56
|
}
|
57
57
|
|
58
58
|
public ExecSession getExec()
|
@@ -96,6 +96,8 @@ public class EmbulkTestRuntime
|
|
96
96
|
});
|
97
97
|
} catch (RuntimeException ex) {
|
98
98
|
throw ex.getCause();
|
99
|
+
} finally {
|
100
|
+
exec.cleanup();
|
99
101
|
}
|
100
102
|
}
|
101
103
|
};
|
data/embulk-docs/src/release.rst
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
Release 0.6.16
|
2
|
+
==================================
|
3
|
+
|
4
|
+
General Changes
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Class loader of plugins lookup classes from plugin's class loader first. This change solves the problem where a plugin uses newer (or older) version of jar library which conflicts with a jar library used by applications embedding embulk.
|
8
|
+
* Added ``ExecSession#cleanup()`` method. Applications embedding embulk as a library needs to call this method at the end of bulk load transaction.
|
9
|
+
|
10
|
+
|
11
|
+
Plugin API
|
12
|
+
------------------
|
13
|
+
|
14
|
+
* Added ``spi.util.TempFileSpace`` and ``spi.Exec.getTempFileSpace``. This utility allows plugins to create temporary files. Because the behavior of cleaning files up is not completely defined yet, it is recommended to test the behavior before deploying code using this API to production.
|
15
|
+
* Added ``spi.unit.LocalFile`` class. Plugins can use this class as a mapped value of configuration file when it needs a path to a local file. This class solves a problem that plugins don't work with distributed executor plugins (such as embulk-executor-mapreduce) if the plugins use ``String`` to get a local file path. Using this class, users can also embed contents of the file in the configuration file instead of setting path to a file.
|
16
|
+
|
17
|
+
|
18
|
+
Note
|
19
|
+
------------------
|
20
|
+
|
21
|
+
* This release includes changes around ClassLoader. Most of plugins should work without modification but it's still highly recommended to test your plugins localy before deploying this version to production systems.
|
22
|
+
|
23
|
+
|
24
|
+
Release Date
|
25
|
+
------------------
|
26
|
+
2015-07-01
|
data/lib/embulk/java/imports.rb
CHANGED
@@ -28,10 +28,10 @@ module Embulk::Java
|
|
28
28
|
java_import 'org.embulk.spi.Column'
|
29
29
|
java_import 'org.embulk.spi.type.Type'
|
30
30
|
java_import 'org.embulk.spi.type.Types'
|
31
|
-
java_import 'org.embulk.spi.PluginClassLoader'
|
32
31
|
java_import 'org.embulk.spi.FileInputRunner'
|
33
32
|
java_import 'org.embulk.spi.FileOutputRunner'
|
34
33
|
java_import 'org.embulk.spi.Exec'
|
34
|
+
java_import 'org.embulk.plugin.PluginClassLoaderFactory'
|
35
35
|
|
36
36
|
# TODO
|
37
37
|
end
|
data/lib/embulk/java_plugin.rb
CHANGED
@@ -6,7 +6,8 @@ module Embulk
|
|
6
6
|
def self.classloader(dir)
|
7
7
|
jars = Dir["#{dir}/**/*.jar"]
|
8
8
|
urls = jars.map {|jar| java.io.File.new(File.expand_path(jar)).toURI.toURL }
|
9
|
-
|
9
|
+
factory = Java.injector.getInstance(Java::PluginClassLoaderFactory.java_class)
|
10
|
+
factory.create(urls, JRuby.runtime.getJRubyClassLoader())
|
10
11
|
end
|
11
12
|
|
12
13
|
def self.register_input(name, class_fqdn, jar_dir)
|
data/lib/embulk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -148,10 +148,14 @@ files:
|
|
148
148
|
- embulk-core/src/main/java/org/embulk/exec/SamplingParserPlugin.java
|
149
149
|
- embulk-core/src/main/java/org/embulk/exec/SetCurrentThreadName.java
|
150
150
|
- embulk-core/src/main/java/org/embulk/exec/SystemConfigModule.java
|
151
|
+
- embulk-core/src/main/java/org/embulk/exec/TempFileAllocator.java
|
151
152
|
- embulk-core/src/main/java/org/embulk/jruby/JRubyPluginSource.java
|
152
153
|
- embulk-core/src/main/java/org/embulk/jruby/JRubyScriptingModule.java
|
153
154
|
- embulk-core/src/main/java/org/embulk/plugin/BuiltinPluginSourceModule.java
|
154
155
|
- embulk-core/src/main/java/org/embulk/plugin/InjectedPluginSource.java
|
156
|
+
- embulk-core/src/main/java/org/embulk/plugin/PluginClassLoader.java
|
157
|
+
- embulk-core/src/main/java/org/embulk/plugin/PluginClassLoaderFactory.java
|
158
|
+
- embulk-core/src/main/java/org/embulk/plugin/PluginClassLoaderModule.java
|
155
159
|
- embulk-core/src/main/java/org/embulk/plugin/PluginManager.java
|
156
160
|
- embulk-core/src/main/java/org/embulk/plugin/PluginSource.java
|
157
161
|
- embulk-core/src/main/java/org/embulk/plugin/PluginSourceNotMatchException.java
|
@@ -185,13 +189,14 @@ files:
|
|
185
189
|
- embulk-core/src/main/java/org/embulk/spi/PageOutput.java
|
186
190
|
- embulk-core/src/main/java/org/embulk/spi/PageReader.java
|
187
191
|
- embulk-core/src/main/java/org/embulk/spi/ParserPlugin.java
|
188
|
-
- embulk-core/src/main/java/org/embulk/spi/PluginClassLoader.java
|
189
192
|
- embulk-core/src/main/java/org/embulk/spi/ProcessState.java
|
190
193
|
- embulk-core/src/main/java/org/embulk/spi/ProcessTask.java
|
191
194
|
- embulk-core/src/main/java/org/embulk/spi/Schema.java
|
192
195
|
- embulk-core/src/main/java/org/embulk/spi/SchemaConfig.java
|
193
196
|
- embulk-core/src/main/java/org/embulk/spi/SchemaConfigException.java
|
194
197
|
- embulk-core/src/main/java/org/embulk/spi/TaskState.java
|
198
|
+
- embulk-core/src/main/java/org/embulk/spi/TempFileException.java
|
199
|
+
- embulk-core/src/main/java/org/embulk/spi/TempFileSpace.java
|
195
200
|
- embulk-core/src/main/java/org/embulk/spi/Transactional.java
|
196
201
|
- embulk-core/src/main/java/org/embulk/spi/TransactionalFileInput.java
|
197
202
|
- embulk-core/src/main/java/org/embulk/spi/TransactionalFileOutput.java
|
@@ -215,6 +220,8 @@ files:
|
|
215
220
|
- embulk-core/src/main/java/org/embulk/spi/type/TypeDeserializer.java
|
216
221
|
- embulk-core/src/main/java/org/embulk/spi/type/Types.java
|
217
222
|
- embulk-core/src/main/java/org/embulk/spi/unit/ByteSize.java
|
223
|
+
- embulk-core/src/main/java/org/embulk/spi/unit/LocalFile.java
|
224
|
+
- embulk-core/src/main/java/org/embulk/spi/unit/LocalFileSerDe.java
|
218
225
|
- embulk-core/src/main/java/org/embulk/spi/util/CharsetSerDe.java
|
219
226
|
- embulk-core/src/main/java/org/embulk/spi/util/Decoders.java
|
220
227
|
- embulk-core/src/main/java/org/embulk/spi/util/DynamicColumnNotFoundException.java
|
@@ -249,6 +256,8 @@ files:
|
|
249
256
|
- embulk-core/src/main/resources/embulk/logback-color.xml
|
250
257
|
- embulk-core/src/main/resources/embulk/logback-console.xml
|
251
258
|
- embulk-core/src/main/resources/embulk/logback-file.xml
|
259
|
+
- embulk-core/src/main/resources/embulk/parent_first_packages.properties
|
260
|
+
- embulk-core/src/main/resources/embulk/parent_first_resources.properties
|
252
261
|
- embulk-core/src/test/java/org/embulk/EmbulkTestRuntime.java
|
253
262
|
- embulk-core/src/test/java/org/embulk/GuiceBinder.java
|
254
263
|
- embulk-core/src/test/java/org/embulk/RandomManager.java
|
@@ -319,6 +328,7 @@ files:
|
|
319
328
|
- embulk-docs/src/release/release-0.6.13.rst
|
320
329
|
- embulk-docs/src/release/release-0.6.14.rst
|
321
330
|
- embulk-docs/src/release/release-0.6.15.rst
|
331
|
+
- embulk-docs/src/release/release-0.6.16.rst
|
322
332
|
- embulk-docs/src/release/release-0.6.2.rst
|
323
333
|
- embulk-docs/src/release/release-0.6.3.rst
|
324
334
|
- embulk-docs/src/release/release-0.6.4.rst
|
@@ -435,8 +445,8 @@ files:
|
|
435
445
|
- classpath/bval-jsr303-0.5.jar
|
436
446
|
- classpath/commons-beanutils-core-1.8.3.jar
|
437
447
|
- classpath/commons-lang3-3.1.jar
|
438
|
-
- classpath/embulk-core-0.6.
|
439
|
-
- classpath/embulk-standards-0.6.
|
448
|
+
- classpath/embulk-core-0.6.16.jar
|
449
|
+
- classpath/embulk-standards-0.6.16.jar
|
440
450
|
- classpath/guava-18.0.jar
|
441
451
|
- classpath/guice-4.0.jar
|
442
452
|
- classpath/guice-multibindings-4.0.jar
|