embulk-input-sftp 0.1.0
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 +7 -0
- data/.gitignore +14 -0
- data/README.md +126 -0
- data/build.gradle +95 -0
- data/config/checkstyle/checkstyle.xml +128 -0
- data/config/checkstyle/default.xml +108 -0
- data/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.properties +6 -0
- data/gradlew +160 -0
- data/gradlew.bat +90 -0
- data/lib/embulk/input/sftp.rb +3 -0
- data/src/main/java/org/embulk/input/sftp/PluginTask.java +67 -0
- data/src/main/java/org/embulk/input/sftp/ProxyTask.java +85 -0
- data/src/main/java/org/embulk/input/sftp/SftpFileInput.java +217 -0
- data/src/main/java/org/embulk/input/sftp/SftpFileInputPlugin.java +67 -0
- data/src/main/java/org/embulk/input/sftp/SingleFileProvider.java +71 -0
- data/src/test/java/org/embulk/input/sftp/TestSftpFileInputPlugin.java +5 -0
- data/src/test/resources/id_rsa +30 -0
- data/src/test/resources/id_rsa.pub +1 -0
- metadata +95 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
package org.embulk.input.sftp;
|
2
|
+
|
3
|
+
import org.embulk.config.ConfigDiff;
|
4
|
+
import org.embulk.config.ConfigSource;
|
5
|
+
import org.embulk.config.TaskReport;
|
6
|
+
import org.embulk.config.TaskSource;
|
7
|
+
import org.embulk.spi.Exec;
|
8
|
+
import org.embulk.spi.FileInputPlugin;
|
9
|
+
import org.embulk.spi.TransactionalFileInput;
|
10
|
+
|
11
|
+
import java.util.ArrayList;
|
12
|
+
import java.util.Collections;
|
13
|
+
import java.util.List;
|
14
|
+
|
15
|
+
public class SftpFileInputPlugin
|
16
|
+
implements FileInputPlugin
|
17
|
+
{
|
18
|
+
@Override
|
19
|
+
public ConfigDiff transaction(ConfigSource config, FileInputPlugin.Control control)
|
20
|
+
{
|
21
|
+
PluginTask task = config.loadConfig(PluginTask.class);
|
22
|
+
|
23
|
+
// list files recursively
|
24
|
+
task.setFiles(SftpFileInput.listFilesByPrefix(task));
|
25
|
+
// number of processors is same with number of files
|
26
|
+
return resume(task.dump(), task.getFiles().size(), control);
|
27
|
+
}
|
28
|
+
|
29
|
+
@Override
|
30
|
+
public ConfigDiff resume(TaskSource taskSource,
|
31
|
+
int taskCount,
|
32
|
+
FileInputPlugin.Control control)
|
33
|
+
{
|
34
|
+
PluginTask task = taskSource.loadTask(PluginTask.class);
|
35
|
+
|
36
|
+
control.run(taskSource, taskCount);
|
37
|
+
|
38
|
+
ConfigDiff configDiff = Exec.newConfigDiff();
|
39
|
+
|
40
|
+
List<String> files = new ArrayList<String>(task.getFiles());
|
41
|
+
if (files.isEmpty()) {
|
42
|
+
if (task.getLastPath().isPresent()) {
|
43
|
+
configDiff.set("last_path", task.getLastPath().get());
|
44
|
+
}
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
Collections.sort(files);
|
48
|
+
configDiff.set("last_path", files.get(files.size() - 1));
|
49
|
+
}
|
50
|
+
|
51
|
+
return configDiff;
|
52
|
+
}
|
53
|
+
|
54
|
+
@Override
|
55
|
+
public void cleanup(TaskSource taskSource,
|
56
|
+
int taskCount,
|
57
|
+
List<TaskReport> successTaskReports)
|
58
|
+
{
|
59
|
+
}
|
60
|
+
|
61
|
+
@Override
|
62
|
+
public TransactionalFileInput open(TaskSource taskSource, int taskIndex)
|
63
|
+
{
|
64
|
+
PluginTask task = taskSource.loadTask(PluginTask.class);
|
65
|
+
return new SftpFileInput(task, taskIndex);
|
66
|
+
}
|
67
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
package org.embulk.input.sftp;
|
2
|
+
|
3
|
+
import org.apache.commons.vfs2.FileObject;
|
4
|
+
import org.apache.commons.vfs2.FileSystemException;
|
5
|
+
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
|
6
|
+
import org.embulk.spi.Exec;
|
7
|
+
import org.embulk.spi.util.InputStreamFileInput;
|
8
|
+
import org.slf4j.Logger;
|
9
|
+
|
10
|
+
import java.io.IOException;
|
11
|
+
import java.io.InputStream;
|
12
|
+
|
13
|
+
public class SingleFileProvider
|
14
|
+
implements InputStreamFileInput.Provider
|
15
|
+
{
|
16
|
+
private final StandardFileSystemManager manager;
|
17
|
+
private final String key;
|
18
|
+
private final PluginTask task;
|
19
|
+
private final int maxConnectionRetry;
|
20
|
+
private boolean opened = false;
|
21
|
+
private final Logger log = Exec.getLogger(SingleFileProvider.class);
|
22
|
+
|
23
|
+
public SingleFileProvider(PluginTask task, int taskIndex, StandardFileSystemManager manager)
|
24
|
+
{
|
25
|
+
this.manager = manager;
|
26
|
+
this.key = task.getFiles().get(taskIndex);
|
27
|
+
this.task = task;
|
28
|
+
this.maxConnectionRetry = task.getMaxConnectionRetry();
|
29
|
+
}
|
30
|
+
|
31
|
+
@Override
|
32
|
+
public InputStream openNext() throws IOException
|
33
|
+
{
|
34
|
+
if (opened) {
|
35
|
+
return null;
|
36
|
+
}
|
37
|
+
opened = true;
|
38
|
+
|
39
|
+
int count = 0;
|
40
|
+
while (true) {
|
41
|
+
try {
|
42
|
+
FileObject file = manager.resolveFile(key, SftpFileInput.initializeFsOptions(task));
|
43
|
+
log.info("Starting to download file {}", key);
|
44
|
+
|
45
|
+
return file.getContent().getInputStream();
|
46
|
+
}
|
47
|
+
catch (FileSystemException ex) {
|
48
|
+
if (++count == maxConnectionRetry) {
|
49
|
+
throw ex;
|
50
|
+
}
|
51
|
+
log.warn("failed to connect sftp server: " + ex.getMessage(), ex);
|
52
|
+
|
53
|
+
try {
|
54
|
+
long sleepTime = ((long) Math.pow(2, count) * 1000);
|
55
|
+
log.warn("sleep in next connection retry: {} milliseconds", sleepTime);
|
56
|
+
Thread.sleep(sleepTime); // milliseconds
|
57
|
+
}
|
58
|
+
catch (InterruptedException ex2) {
|
59
|
+
// Ignore this exception because this exception is just about `sleep`.
|
60
|
+
log.warn(ex2.getMessage(), ex2);
|
61
|
+
}
|
62
|
+
log.warn("retrying to connect sftp server: " + count + " times");
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
@Override
|
68
|
+
public void close()
|
69
|
+
{
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: AES-128-CBC,D2F2C35989F5D5F3CA9482CFDE382598
|
4
|
+
|
5
|
+
k11GNDLfBbb3QV1GZs/78aMiznfXE3ZuJhSm3W9pWRq5h2DAxOTKYUuTvlbUtlQt
|
6
|
+
N5y708MCynftaeARdCTjnoDRhm2SHHc7JiN4g1cBuVaqst3SOxZvbITrtW0xqW0q
|
7
|
+
XvEiud5RSUwwXgjUPJFXNtchQOhYvsm7HzUOH8K8E6if65dD7gyekF8Smo1alRzB
|
8
|
+
p40FVty81elOO5+tFJuXJTxayNcUh8JHjrFTUToN8zAiAkIkvqd9JZe+jTRZjoYr
|
9
|
+
H/yFiWm6sHFEHsAPnvdYjDl870pGs1qqm74CZKu383C5ioFd9aK7LaZBi5gvz8HX
|
10
|
+
anLK1DZSEUdhqSBAHEP0IvLvFNtY/5Hc0ohQt+BHOpnLjoSzckUJjly8bzmYrT1L
|
11
|
+
uXBLYkLnFaFz4t/HowSfF8WgRqUh8dDcXDWuXkvMy5WV6YII5hx0/PN8F9mE78Jc
|
12
|
+
jeIcuQBV7MuBaJDmpktB2DH+Zt1T/391MGTvU3ZwaNcoDCuavt9uR1OtgTXvbw7w
|
13
|
+
qY/uEfasVzXxs6paRY6E85uUuFQy2XQIBqfermQYBg/vncAIWRfXh5AcgKktE0XH
|
14
|
+
LczzalWwdzakCJ816htYDe4311K0oPjxStEMFGW390MuKMnpyK2IDBTBub5tzcMl
|
15
|
+
BGCtNoJUrPj6Ty/vIhiADEMgs63C5sejyVnL9CiJGC/we0Ihe8akY5l2h9VV+C+8
|
16
|
+
80qQjdNU2yGu8Jta1avFmzu/1wWN3KAO/GujjbhC8thAizu1Of62q+FH+sbni9Lr
|
17
|
+
raJypD1iVsvIkNlwQpAJVJz4mFgLvJBIazc5unWrmOLdUolQ9/7rCSKXUBHF1I7G
|
18
|
+
5MW1YOyBmgNbagCNoE1W4VBF9vafBxtoi1FYPP1uM0JbXAEZLGSWcm9N8hlxx+EP
|
19
|
+
AxATHpOBxgUYHUJK9hlga0AlZ9+BSU/WhDdLtYgFz9cm7b1571wPPAReXYMuip+E
|
20
|
+
Rh0FGWTQfRZ20Vqh5wt4zat7wvCz65dh/SPiZ+H1/qMTpX3LF9dH/4++H13k2xPb
|
21
|
+
P78L74i4tPLpKnU0RmjZc652SCQ2th8DEihkPrHDrClWDuZoSx/b2gQEq26+ys7P
|
22
|
+
1Ftvjdejh13ZyY4IsVzfRtABU5ma3iHUoL09wYZFi2TAfSEq+zNpNg3MwCILhCs/
|
23
|
+
TEM2zXPUJgVoxVgWp1Vfu+1MMubXSShsz3R6Ec/AC22PdpIu6h/7twPZOD+zjOuv
|
24
|
+
r6lbQs33OLmhp1I+7xy9CNRHCjm7GExk/l3ZudCxJGyQ/a4s8iSiIhJ0R8LbX3Ux
|
25
|
+
VT/ZAQjjxAMvCEpGcuricrVbo+QXF5epgtV73bQj99LCYtS4rFk6Pwn/06IxbKlN
|
26
|
+
/V+ltFNSexyxRFcBxiq5e7G2zQEcdNLAFXvAXHk6nULUWuY5Nz0ugdUyJVytrNGk
|
27
|
+
Sd2501Lz6qzH5WpLcg3RB+i5aTE+SuAZHOpaBqL9YHMZ2TFtCfV/iTJQEFG/kYdL
|
28
|
+
Skiu+dcYjO4kSiLsznxSAPGvmZrUHFk5f2MzEuCw+ibSfsO5IEcjg9PD+zXbbzTc
|
29
|
+
VK8MzAv8y+3OG6M4pzMAwEsxOUgflyVZgjEA1lOPplkmj3Q0NOgipczi28qNUYeh
|
30
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtW2TpgsOXiZXmIycRsrRKN/IC8LeLSIkDBs23ut4dvLn0sNTdY7C5QdemFHN2zqzHI85U0kKZ5VorEXF/bfbRImXSEWafhGNN/DsdLNGpIqarXVsQ9j8/Yt+KngubjBM/uNZt62zBNk+jyU7OyVAyHtjW7+9uBl7ApGGiIEBOJZJcTFkbUiXqwzWtEtsOPaEdrc7GVJaJ8bwARptYbn32Z8gFNHwQyBBQiTXWsGX42EfYYs1HcJlH3GkDLVOsvrgHAN80dDzrJrvSTsFURThnvrYezubV4y4EvRhwF9BUL8b+Xz8senNpWEla/Qv1IQLSB/UwUhIiXYtpamS7NIFx
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: embulk-input-sftp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Satoshi Akama
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ~>
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.0'
|
19
|
+
name: bundler
|
20
|
+
prerelease: false
|
21
|
+
type: :development
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '10.0'
|
33
|
+
name: rake
|
34
|
+
prerelease: false
|
35
|
+
type: :development
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: Reads files stored on remote server using SFTP.
|
42
|
+
email:
|
43
|
+
- satoshiakama@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- README.md
|
50
|
+
- build.gradle
|
51
|
+
- config/checkstyle/checkstyle.xml
|
52
|
+
- config/checkstyle/default.xml
|
53
|
+
- gradle/wrapper/gradle-wrapper.jar
|
54
|
+
- gradle/wrapper/gradle-wrapper.properties
|
55
|
+
- gradlew
|
56
|
+
- gradlew.bat
|
57
|
+
- lib/embulk/input/sftp.rb
|
58
|
+
- src/main/java/org/embulk/input/sftp/PluginTask.java
|
59
|
+
- src/main/java/org/embulk/input/sftp/ProxyTask.java
|
60
|
+
- src/main/java/org/embulk/input/sftp/SftpFileInput.java
|
61
|
+
- src/main/java/org/embulk/input/sftp/SftpFileInputPlugin.java
|
62
|
+
- src/main/java/org/embulk/input/sftp/SingleFileProvider.java
|
63
|
+
- src/test/java/org/embulk/input/sftp/TestSftpFileInputPlugin.java
|
64
|
+
- src/test/resources/id_rsa
|
65
|
+
- src/test/resources/id_rsa.pub
|
66
|
+
- classpath/commons-io-1.3.2.jar
|
67
|
+
- classpath/commons-logging-1.2.jar
|
68
|
+
- classpath/commons-vfs2-2.1.1660580.2.jar
|
69
|
+
- classpath/embulk-input-sftp-0.1.0.jar
|
70
|
+
- classpath/jsch-0.1.53.jar
|
71
|
+
homepage: https://github.com/sakama/embulk-input-sftp
|
72
|
+
licenses:
|
73
|
+
- Apache-2.0
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.1.9
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: SFTP file input plugin for Embulk
|
95
|
+
test_files: []
|