embulk-input-sftp 0.2.0 → 0.2.1

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: 2afbf35e073d8e31985a7c797395c796828aa675
4
- data.tar.gz: 73667da5ec1be837b3c5811969dc5c4ba4014731
3
+ metadata.gz: 2437f248e08389b72d6954dbb9da3dd6db93964a
4
+ data.tar.gz: cb24da548a14d3b986ebb21b1f114f4d69bf2962
5
5
  SHA512:
6
- metadata.gz: 3bb521683b3668ef39f71233755eaabc3f2b67578e711efe942e095dbf97969f1b7aeeb72bb5cbb422a7eeb3d4dc9384e549e0a9f94a331a3829c0d5d779bb8a
7
- data.tar.gz: cbb3f79afc30b70fca469bd6012653d13e58983d03934a48d76e474c277e9cc7b79161a03eaf48b38c2ce7389048545cd0dfa77c7d373a216eec556e84941aee
6
+ metadata.gz: 240d0bf66262aabc11f90fa0f53c8e83b11253a2cee7cf384d739804d7dfa074ffe3986f703f1d2fed803bc45c69b1d796ec37c736c6d2fd738e153e4710adf6
7
+ data.tar.gz: 5ae478d9b5d8ce6429c56579b263d84f25214e1f38442e13494e3d6e49216fea3efa9c6eaa7d0754020583eee80d749a8031b2b7912aabab6d8e8c7332014568
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.2.1 - 2016-09-12
2
+ * [maintenance] Fix last_path generation failure when password contains special chars [#15](https://github.com/sakama/embulk-input-sftp/pull/15)
3
+
1
4
  ## 0.2.0 - 2016-08-19
2
5
 
3
6
  * [new feature] Support incremental option [#11](https://github.com/sakama/embulk-input-sftp/pull/11)
data/build.gradle CHANGED
@@ -14,7 +14,7 @@ configurations {
14
14
  provided
15
15
  }
16
16
 
17
- version = "0.2.0"
17
+ version = "0.2.1"
18
18
 
19
19
  sourceCompatibility = 1.7
20
20
  targetCompatibility = 1.7
@@ -143,19 +143,82 @@ public class SftpFileInput
143
143
  }
144
144
  }
145
145
 
146
- public static String getRelativePath(Optional<String> path)
146
+ public static String getRelativePath(PluginTask task, Optional<String> uri)
147
147
  {
148
148
  try {
149
- if (path.isPresent()) {
150
- return new URI(path.get()).getPath();
149
+ if (!uri.isPresent()) {
150
+ return null;
151
+ }
152
+ else if (task.getPassword().isPresent()) {
153
+ return getRelativePathFromURIwithPassword(task, uri);
151
154
  }
152
155
  else {
153
- return null;
156
+ return new URI(uri.get()).getPath();
154
157
  }
155
158
  }
156
159
  catch (URISyntaxException ex) {
157
- return null;
160
+ throw new ConfigException("Failed to generate last_path due to URI parse failure that contains invalid file path.", ex);
161
+ }
162
+ }
163
+
164
+ private static String getRelativePathFromURIwithPassword(final PluginTask task, final Optional<String> uri)
165
+ {
166
+ try {
167
+ return retryExecutor()
168
+ .withRetryLimit(task.getMaxConnectionRetry())
169
+ .withInitialRetryWait(500)
170
+ .withMaxRetryWait(30 * 1000)
171
+ .runInterruptible(new Retryable<String>() {
172
+ @Override
173
+ public String call() throws URISyntaxException, IOException
174
+ {
175
+ log.info("Creating last_path from URI contains password in FileList.");
176
+ StandardFileSystemManager manager = initializeStandardFileSystemManager();
177
+
178
+ String prefix = new URI("sftp", initializeUserInfo(task), task.getHost(), task.getPort(), null, null, null).toString();
179
+ prefix = manager.resolveFile(prefix).toString();
180
+ // To avoid URI parse failure when password contains special characters
181
+ String newUri = uri.get().replace(prefix, "sftp://user:password@example.com/");
182
+
183
+ return new URI(newUri).getPath();
184
+ }
185
+
186
+ @Override
187
+ public boolean isRetryableException(Exception exception)
188
+ {
189
+ if (exception instanceof URISyntaxException) {
190
+ // Don't throw cause because URISyntaxException shows password
191
+ throw new ConfigException("Failed to generate last_path due to URI parse failure that contains invalid file path or password.");
192
+ }
193
+ return true;
194
+ }
195
+
196
+ @Override
197
+ public void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait) throws RetryGiveupException
198
+ {
199
+ String message = String.format("SFTP List request failed. Retrying %d/%d after %d seconds. Message: %s",
200
+ retryCount, retryLimit, retryWait / 1000, exception.getMessage());
201
+ if (retryCount % 3 == 0) {
202
+ log.warn(message, exception);
203
+ }
204
+ else {
205
+ log.warn(message);
206
+ }
207
+ }
208
+
209
+ @Override
210
+ public void onGiveup(Exception firstException, Exception lastException) throws RetryGiveupException
211
+ {
212
+ }
213
+ });
214
+ }
215
+ catch (RetryGiveupException ex) {
216
+ throw new ConfigException("Failed to generate last_path due to FTP connection failure");
217
+ }
218
+ catch (InterruptedException ex) {
219
+ Throwables.propagate(ex);
158
220
  }
221
+ return null;
159
222
  }
160
223
 
161
224
  public static FileList listFilesByPrefix(final PluginTask task)
@@ -30,11 +30,15 @@ public class SftpFileInputPlugin
30
30
  FileInputPlugin.Control control)
31
31
  {
32
32
  PluginTask task = taskSource.loadTask(PluginTask.class);
33
+ String lastPath = null;
34
+ if (task.getIncremental()) {
35
+ lastPath = SftpFileInput.getRelativePath(task, task.getFiles().getLastPath(task.getLastPath()));
36
+ }
33
37
  control.run(taskSource, taskCount);
34
38
 
35
39
  ConfigDiff configDiff = Exec.newConfigDiff();
36
- if (task.getIncremental()) {
37
- configDiff.set("last_path", SftpFileInput.getRelativePath(task.getFiles().getLastPath(task.getLastPath())));
40
+ if (task.getIncremental() && lastPath != null) {
41
+ configDiff.set("last_path", lastPath);
38
42
  }
39
43
 
40
44
  return configDiff;
@@ -227,7 +227,7 @@ public class TestSftpFileInputPlugin
227
227
 
228
228
  assertEquals(expected.get(0), actual.get(0));
229
229
  assertEquals(expected.get(1), actual.get(1));
230
- assertEquals(SftpFileInput.getRelativePath(Optional.of(expected.get(1).get(0))), configDiff.get(String.class, "last_path"));
230
+ assertEquals(SftpFileInput.getRelativePath(task, Optional.of(expected.get(1).get(0))), configDiff.get(String.class, "last_path"));
231
231
  }
232
232
 
233
233
  @Test
@@ -373,6 +373,23 @@ public class TestSftpFileInputPlugin
373
373
  assertEquals(SftpFileSystemConfigBuilder.PROXY_STREAM, builder.getProxyType(fsOptions));
374
374
  }
375
375
 
376
+ @Test
377
+ public void testGetRelativePath()
378
+ {
379
+ ConfigSource conf = config();
380
+ String expected = "/path/to/sample.csv";
381
+
382
+ conf.set("password", "ABCDE");
383
+ PluginTask task = config.loadConfig(PluginTask.class);
384
+ String uri = SftpFileInput.getSftpFileUri(task, "/path/to/sample.csv");
385
+ assertEquals(expected, SftpFileInput.getRelativePath(task, Optional.of(uri)));
386
+
387
+ conf.set("password", "ABCD#$¥!%'\"@?<>\\&/_^~|-=+-,{}[]()");
388
+ task = config.loadConfig(PluginTask.class);
389
+ uri = SftpFileInput.getSftpFileUri(task, "/path/to/sample.csv");
390
+ assertEquals(expected, SftpFileInput.getRelativePath(task, Optional.of(uri)));
391
+ }
392
+
376
393
  private SshServer createSshServer(String host, int port, final String sshUsername, final String sshPassword)
377
394
  {
378
395
  // setup a mock sftp server
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-sftp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Satoshi Akama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-19 00:00:00.000000000 Z
11
+ date: 2016-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -72,7 +72,7 @@ files:
72
72
  - classpath/commons-io-1.3.2.jar
73
73
  - classpath/commons-logging-1.2.jar
74
74
  - classpath/commons-vfs2-2.1.jar
75
- - classpath/embulk-input-sftp-0.2.0.jar
75
+ - classpath/embulk-input-sftp-0.2.1.jar
76
76
  - classpath/jsch-0.1.53.jar
77
77
  homepage: https://github.com/embulk/embulk-input-sftp
78
78
  licenses: