embulk-input-remote 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b37822e56bd1e3b9726a1cdab656c33e42b4d3cf
4
- data.tar.gz: 3e567cc0300e1319bccd86fea0410ec7193fc269
3
+ metadata.gz: 1ea2dc9f5f71195a19ac5f0a5a3e96d4020a02b2
4
+ data.tar.gz: 4081a11e980990e00243581ec48016cd6bd15bbe
5
5
  SHA512:
6
- metadata.gz: 4d2157a0e77f281c030535eaf37ab47f28f4f73b5d85d1749ed7fd56fd2fb2676c6661b53271c67e0912885e88028dbd047f5ae4757036962b222c077a9e80b1
7
- data.tar.gz: 87ded4537e43dd1477462998083732f4e2dfe0b274a007380a9c4bec1df7c4020a9a792b8681921e3f552a9d6f311fef772560bb7d0bb44872519d55005116e3
6
+ metadata.gz: 93cfc49c50e5844ad4e9a9b51ea8513d2e8f422866d8c52542f2b306605a78896f1d805bd68a7e21e77114af525e1c3f5510c98b1b74f94743360a79074eb54a
7
+ data.tar.gz: 34c3fcb851fa472051aeaa77182bfcf89ff2f8b3ee021681cd3904e53ffb31e55719bb33949ed2326ebfc29a2996c4ad3ccd97117358f8abb0c469df5cd67c37
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Remote file input plugin for Embulk
1
+ # Remote file input plugin for [Embulk](https://github.com/embulk/embulk)
2
2
 
3
3
  This plugin load data from Remote hosts by SCP
4
4
 
@@ -15,6 +15,7 @@ This plugin load data from Remote hosts by SCP
15
15
  - **hosts_separator**: Separator for "hosts_command" result (string, default: " ")
16
16
  - **path**: Path of remote host (File or Directory) (string, default: "")
17
17
  - **path_command**: Command for getting path (Windows not supported). If given the option "path" is overwritten. (string, default: null)
18
+ - **ignore_not_found_hosts**: If the option is true, Hosts which file(or directory) is not found is skipped. (Means it's not included in resume target.) (boolean, default: false)
18
19
  - **auth**: SSH authentication setting (hash, default: {})
19
20
  - **user**: SSH username (string, default: execute user)
20
21
  - **type**: public_key or password (string, default: public_key)
@@ -33,6 +34,7 @@ in:
33
34
  # hosts_separator: ','
34
35
  path: /some/path/20150414125923
35
36
  # path_command: echo /some/path/`date "+%Y%m%d%H%M%S"`
37
+ ignore_not_found_hosts: true
36
38
  auth:
37
39
  user: {username}
38
40
  type: public_key
data/build.gradle CHANGED
@@ -13,7 +13,7 @@ configurations {
13
13
  provided
14
14
  }
15
15
 
16
- version = "0.1.1"
16
+ version = "0.1.2"
17
17
 
18
18
  dependencies {
19
19
  compile "org.embulk:embulk-core:0.6.1"
data/gradlew.bat CHANGED
@@ -1,90 +1,90 @@
1
- @if "%DEBUG%" == "" @echo off
2
- @rem ##########################################################################
3
- @rem
4
- @rem Gradle startup script for Windows
5
- @rem
6
- @rem ##########################################################################
7
-
8
- @rem Set local scope for the variables with windows NT shell
9
- if "%OS%"=="Windows_NT" setlocal
10
-
11
- @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12
- set DEFAULT_JVM_OPTS=
13
-
14
- set DIRNAME=%~dp0
15
- if "%DIRNAME%" == "" set DIRNAME=.
16
- set APP_BASE_NAME=%~n0
17
- set APP_HOME=%DIRNAME%
18
-
19
- @rem Find java.exe
20
- if defined JAVA_HOME goto findJavaFromJavaHome
21
-
22
- set JAVA_EXE=java.exe
23
- %JAVA_EXE% -version >NUL 2>&1
24
- if "%ERRORLEVEL%" == "0" goto init
25
-
26
- echo.
27
- echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
- echo.
29
- echo Please set the JAVA_HOME variable in your environment to match the
30
- echo location of your Java installation.
31
-
32
- goto fail
33
-
34
- :findJavaFromJavaHome
35
- set JAVA_HOME=%JAVA_HOME:"=%
36
- set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
-
38
- if exist "%JAVA_EXE%" goto init
39
-
40
- echo.
41
- echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
- echo.
43
- echo Please set the JAVA_HOME variable in your environment to match the
44
- echo location of your Java installation.
45
-
46
- goto fail
47
-
48
- :init
49
- @rem Get command-line arguments, handling Windowz variants
50
-
51
- if not "%OS%" == "Windows_NT" goto win9xME_args
52
- if "%@eval[2+2]" == "4" goto 4NT_args
53
-
54
- :win9xME_args
55
- @rem Slurp the command line arguments.
56
- set CMD_LINE_ARGS=
57
- set _SKIP=2
58
-
59
- :win9xME_args_slurp
60
- if "x%~1" == "x" goto execute
61
-
62
- set CMD_LINE_ARGS=%*
63
- goto execute
64
-
65
- :4NT_args
66
- @rem Get arguments from the 4NT Shell from JP Software
67
- set CMD_LINE_ARGS=%$
68
-
69
- :execute
70
- @rem Setup the command line
71
-
72
- set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73
-
74
- @rem Execute Gradle
75
- "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76
-
77
- :end
78
- @rem End local scope for the variables with windows NT shell
79
- if "%ERRORLEVEL%"=="0" goto mainEnd
80
-
81
- :fail
82
- rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83
- rem the _cmd.exe /c_ return code!
84
- if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85
- exit /b 1
86
-
87
- :mainEnd
88
- if "%OS%"=="Windows_NT" endlocal
89
-
90
- :omega
1
+ @if "%DEBUG%" == "" @echo off
2
+ @rem ##########################################################################
3
+ @rem
4
+ @rem Gradle startup script for Windows
5
+ @rem
6
+ @rem ##########################################################################
7
+
8
+ @rem Set local scope for the variables with windows NT shell
9
+ if "%OS%"=="Windows_NT" setlocal
10
+
11
+ @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12
+ set DEFAULT_JVM_OPTS=
13
+
14
+ set DIRNAME=%~dp0
15
+ if "%DIRNAME%" == "" set DIRNAME=.
16
+ set APP_BASE_NAME=%~n0
17
+ set APP_HOME=%DIRNAME%
18
+
19
+ @rem Find java.exe
20
+ if defined JAVA_HOME goto findJavaFromJavaHome
21
+
22
+ set JAVA_EXE=java.exe
23
+ %JAVA_EXE% -version >NUL 2>&1
24
+ if "%ERRORLEVEL%" == "0" goto init
25
+
26
+ echo.
27
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
+ echo.
29
+ echo Please set the JAVA_HOME variable in your environment to match the
30
+ echo location of your Java installation.
31
+
32
+ goto fail
33
+
34
+ :findJavaFromJavaHome
35
+ set JAVA_HOME=%JAVA_HOME:"=%
36
+ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
+
38
+ if exist "%JAVA_EXE%" goto init
39
+
40
+ echo.
41
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
+ echo.
43
+ echo Please set the JAVA_HOME variable in your environment to match the
44
+ echo location of your Java installation.
45
+
46
+ goto fail
47
+
48
+ :init
49
+ @rem Get command-line arguments, handling Windowz variants
50
+
51
+ if not "%OS%" == "Windows_NT" goto win9xME_args
52
+ if "%@eval[2+2]" == "4" goto 4NT_args
53
+
54
+ :win9xME_args
55
+ @rem Slurp the command line arguments.
56
+ set CMD_LINE_ARGS=
57
+ set _SKIP=2
58
+
59
+ :win9xME_args_slurp
60
+ if "x%~1" == "x" goto execute
61
+
62
+ set CMD_LINE_ARGS=%*
63
+ goto execute
64
+
65
+ :4NT_args
66
+ @rem Get arguments from the 4NT Shell from JP Software
67
+ set CMD_LINE_ARGS=%$
68
+
69
+ :execute
70
+ @rem Setup the command line
71
+
72
+ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73
+
74
+ @rem Execute Gradle
75
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76
+
77
+ :end
78
+ @rem End local scope for the variables with windows NT shell
79
+ if "%ERRORLEVEL%"=="0" goto mainEnd
80
+
81
+ :fail
82
+ rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83
+ rem the _cmd.exe /c_ return code!
84
+ if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85
+ exit /b 1
86
+
87
+ :mainEnd
88
+ if "%OS%"=="Windows_NT" endlocal
89
+
90
+ :omega
@@ -6,7 +6,6 @@ import java.io.ByteArrayOutputStream;
6
6
  import java.io.IOException;
7
7
  import java.io.InputStream;
8
8
  import java.io.InputStreamReader;
9
- import java.io.OutputStream;
10
9
  import java.util.ArrayList;
11
10
  import java.util.Arrays;
12
11
  import java.util.Collections;
@@ -17,9 +16,6 @@ import com.fasterxml.jackson.annotation.JsonCreator;
17
16
  import com.fasterxml.jackson.annotation.JsonProperty;
18
17
  import com.google.common.base.Optional;
19
18
  import com.google.common.collect.ImmutableList;
20
- import net.schmizz.sshj.SSHClient;
21
- import net.schmizz.sshj.xfer.InMemoryDestFile;
22
- import net.schmizz.sshj.xfer.LocalDestFile;
23
19
  import org.embulk.config.CommitReport;
24
20
  import org.embulk.config.Config;
25
21
  import org.embulk.config.ConfigDefault;
@@ -28,6 +24,7 @@ import org.embulk.config.ConfigInject;
28
24
  import org.embulk.config.ConfigSource;
29
25
  import org.embulk.config.Task;
30
26
  import org.embulk.config.TaskSource;
27
+ import org.embulk.input.remote.SSHClient;
31
28
  import org.embulk.spi.BufferAllocator;
32
29
  import org.embulk.spi.Exec;
33
30
  import org.embulk.spi.FileInputPlugin;
@@ -65,6 +62,10 @@ public class RemoteFileInputPlugin
65
62
  @ConfigDefault("{}")
66
63
  public Map<String, String> getAuth();
67
64
 
65
+ @Config("ignore_not_found_hosts")
66
+ @ConfigDefault("false")
67
+ public boolean getIgnoreNotFoundHosts();
68
+
68
69
  @Config("last_target")
69
70
  @ConfigDefault("null")
70
71
  public Optional<Target> getLastTarget();
@@ -84,19 +85,21 @@ public class RemoteFileInputPlugin
84
85
  @Override
85
86
  public ConfigDiff transaction(ConfigSource config, FileInputPlugin.Control control) {
86
87
  PluginTask task = config.loadConfig(PluginTask.class);
88
+ try {
89
+ List<Target> targets = listTargets(task);
90
+ log.info("Loading targets {}", targets);
91
+ task.setTargets(targets);
92
+
93
+ // number of processors is same with number of targets
94
+ int taskCount = targets.size();
95
+ return resume(task.dump(), taskCount, control);
87
96
 
88
- List<Target> targets = listTargets(task);
89
- log.info("Loading targets {}", targets);
90
- task.setTargets(targets);
91
-
92
- // number of processors is same with number of targets
93
- int taskCount = targets.size();
94
- return resume(task.dump(), taskCount, control);
97
+ } catch (IOException e) {
98
+ throw new RuntimeException(e);
99
+ }
95
100
  }
96
101
 
97
- private List<Target> listTargets(PluginTask task) {
98
- task.getHostsCommand().orNull();
99
-
102
+ private List<Target> listTargets(PluginTask task) throws IOException {
100
103
  final List<String> hosts = listHosts(task);
101
104
  final String path = getPath(task);
102
105
 
@@ -104,7 +107,15 @@ public class RemoteFileInputPlugin
104
107
  Target lastTarget = task.getLastTarget().orNull();
105
108
  for (String host : hosts) {
106
109
  Target target = new Target(host, path);
110
+
107
111
  if (lastTarget == null || target.compareTo(lastTarget) > 0) {
112
+ if (task.getIgnoreNotFoundHosts()) {
113
+ // Check with file existing
114
+ if (!exists(target, task)) {
115
+ continue;
116
+ }
117
+ // This host will fail when "open" method is called.
118
+ }
108
119
  builder.add(target);
109
120
  }
110
121
  }
@@ -182,7 +193,7 @@ public class RemoteFileInputPlugin
182
193
  final Target target = task.getTargets().get(taskIndex);
183
194
 
184
195
  try {
185
- return new PluginFileInput(task, download(target, task.getAuth()));
196
+ return new PluginFileInput(task, download(target, task));
186
197
  } catch (IOException e) {
187
198
  throw new RuntimeException(e);
188
199
  }
@@ -227,55 +238,31 @@ public class RemoteFileInputPlugin
227
238
  public CommitReport commit() {
228
239
  return Exec.newCommitReport();
229
240
  }
241
+ }
230
242
 
243
+ private boolean exists(Target target, PluginTask task) throws IOException {
244
+ try (SSHClient client = new SSHClient()) {
245
+ client.connect(target.getHost(), task.getAuth());
231
246
 
232
- }
247
+ final String checkCmd = "ls " + target.getPath(); // TODO: windows
248
+ final int timeout = 5/* second */;
249
+ final SSHClient.CommandResult commandResult = client.execCommand(checkCmd, timeout);
233
250
 
234
- private InputStream download(Target target, Map<String, String> auth) throws IOException {
235
- SSHClient client = new SSHClient();
236
- client.loadKnownHosts();
237
- InMemoryDestFileImpl memoryDestFile = new InMemoryDestFileImpl();
238
- try {
239
- client.connect(target.getHost());
240
- final String type = auth.get("type") != null ? auth.get("type") : "public_key";
241
- final String user = auth.get("user") != null ? auth.get("user") : System.getProperty("user.name");
242
-
243
- if ("password".equals(type)) {
244
- client.authPassword(user, auth.get("password"));
245
- } else if ("public_key".equals(type)) {
246
- final String key_path = auth.get("key_path");
247
- if (key_path == null) {
248
- client.authPublickey(user);
249
- } else {
250
- client.authPublickey(user, key_path);
251
- }
251
+ if(commandResult.getStatus() != 0) {
252
+ log.warn("Remote file not found. {}", target.toString());
253
+ return false;
252
254
  } else {
253
- throw new UnsupportedOperationException("Unsupported auth type : " + type);
255
+ return true;
254
256
  }
255
- client.newSCPFileTransfer().download(target.getPath(), memoryDestFile);
256
- return new ByteArrayInputStream(memoryDestFile.outputStream.toByteArray());
257
-
258
- } finally {
259
- client.disconnect();
260
257
  }
261
258
  }
262
259
 
263
- public static class InMemoryDestFileImpl extends InMemoryDestFile {
264
-
265
- private ByteArrayOutputStream outputStream;
266
-
267
- public InMemoryDestFileImpl() {
268
- this.outputStream = new ByteArrayOutputStream();
269
- }
270
-
271
- @Override
272
- public OutputStream getOutputStream() throws IOException {
273
- return outputStream;
274
- }
275
-
276
- @Override
277
- public LocalDestFile getTargetDirectory(String dirname) throws IOException {
278
- return this;
260
+ private InputStream download(Target target, PluginTask task) throws IOException {
261
+ try (SSHClient client = new SSHClient()) {
262
+ client.connect(target.getHost(), task.getAuth());
263
+ final ByteArrayOutputStream stream = new ByteArrayOutputStream();
264
+ client.scpDownload(target.getPath(), stream);
265
+ return new ByteArrayInputStream(stream.toByteArray());
279
266
  }
280
267
  }
281
268
 
@@ -0,0 +1,104 @@
1
+ package org.embulk.input.remote;
2
+
3
+ import net.schmizz.sshj.connection.channel.direct.Session;
4
+ import net.schmizz.sshj.xfer.InMemoryDestFile;
5
+ import net.schmizz.sshj.xfer.LocalDestFile;
6
+
7
+ import java.io.Closeable;
8
+ import java.io.IOException;
9
+ import java.io.InputStream;
10
+ import java.io.OutputStream;
11
+ import java.util.Map;
12
+ import java.util.concurrent.TimeUnit;
13
+
14
+ public class SSHClient implements Closeable {
15
+
16
+ private final net.schmizz.sshj.SSHClient client;
17
+
18
+ public SSHClient() {
19
+ this(new net.schmizz.sshj.SSHClient());
20
+ }
21
+
22
+ /* package for test */
23
+ SSHClient(net.schmizz.sshj.SSHClient client) {
24
+ this.client = client;
25
+ }
26
+
27
+ public void connect(String host, Map<String, String> authConfig) throws IOException {
28
+ client.loadKnownHosts();
29
+
30
+ client.connect(host);
31
+
32
+ final String type = authConfig.get("type") != null ? authConfig.get("type") : "public_key";
33
+ final String user = authConfig.get("user") != null ? authConfig.get("user") : System.getProperty("user.name");
34
+
35
+ if ("password".equals(type)) {
36
+ client.authPassword(user, authConfig.get("password"));
37
+ } else if ("public_key".equals(type)) {
38
+ final String key_path = authConfig.get("key_path");
39
+ if (key_path == null) {
40
+ client.authPublickey(user);
41
+ } else {
42
+ client.authPublickey(user, key_path);
43
+ }
44
+ } else {
45
+ throw new UnsupportedOperationException("Unsupported auth type : " + type);
46
+ }
47
+ }
48
+
49
+ public CommandResult execCommand(String command, int timeoutSecond) throws IOException {
50
+ try (final Session session = client.startSession()) {
51
+ final Session.Command cmd = session.exec(command);
52
+ cmd.join(timeoutSecond, TimeUnit.SECONDS);
53
+ return new CommandResult(cmd.getExitStatus(), cmd.getInputStream());
54
+ }
55
+ }
56
+
57
+ public void scpDownload(String path, OutputStream stream) throws IOException {
58
+ client.newSCPFileTransfer().download(path, new InMemoryDestFileImpl(stream));
59
+ }
60
+
61
+ private static class InMemoryDestFileImpl extends InMemoryDestFile {
62
+
63
+ private OutputStream outputStream;
64
+
65
+ public InMemoryDestFileImpl(OutputStream outputStream) {
66
+ this.outputStream = outputStream;
67
+ }
68
+
69
+ @Override
70
+ public OutputStream getOutputStream() throws IOException {
71
+ return outputStream;
72
+ }
73
+
74
+ @Override
75
+ public LocalDestFile getTargetDirectory(String dirname) throws IOException {
76
+ return this;
77
+ }
78
+ }
79
+
80
+ @Override
81
+ public void close() throws IOException {
82
+ if (client != null) {
83
+ client.close();
84
+ }
85
+ }
86
+
87
+ public static class CommandResult {
88
+ int status;
89
+ InputStream stdout;
90
+
91
+ private CommandResult(int status, InputStream stdout) {
92
+ this.status = status;
93
+ this.stdout = stdout;
94
+ }
95
+
96
+ public int getStatus() {
97
+ return status;
98
+ }
99
+
100
+ public InputStream getStdout() {
101
+ return stdout;
102
+ }
103
+ }
104
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-remote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shinichi ISHIMURA
@@ -55,10 +55,11 @@ files:
55
55
  - gradlew.bat
56
56
  - lib/embulk/input/remote.rb
57
57
  - src/main/java/org/embulk/input/RemoteFileInputPlugin.java
58
+ - src/main/java/org/embulk/input/remote/SSHClient.java
58
59
  - src/test/java/org/embulk/input/TestRemoteFileInputPlugin.java
59
60
  - classpath/bcpkix-jdk15on-1.51.jar
60
61
  - classpath/bcprov-jdk15on-1.51.jar
61
- - classpath/embulk-input-remote-0.1.1.jar
62
+ - classpath/embulk-input-remote-0.1.2.jar
62
63
  - classpath/jzlib-1.1.3.jar
63
64
  - classpath/sshj-0.11.0.jar
64
65
  homepage: https://github.com/kamatama41/embulk-input-remote