embulk-input-sftp 0.2.0 → 0.2.1

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 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: