embulk-output-sftp 0.0.4 → 0.0.5

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: 40a3cc8b06b682fe155dc167c0e0fd997a18b4a5
4
- data.tar.gz: 1a0ef68bdb08197ce77cb6e4e897fb05121b142a
3
+ metadata.gz: 865291280d7c6936d0e4f12655a00b854f880153
4
+ data.tar.gz: dfe086b9210d16e7da2e21d5f77e42c38bd7f23b
5
5
  SHA512:
6
- metadata.gz: 378b46609dffc450f10602326e88676f75f29f05b3436dffebaa6722004cff6799a361beb39de318ffaf076908ee00719cdadcedbb29eee1fac97a1a2b33111b
7
- data.tar.gz: 2f383b02a595884182b58ebb36ce3c5b4e804d00ce1f6575cd67099094c5c85f48ec33c2b50bdc070c1d6e80d8e7ce29bc4736b71e45ee43107f94b84cc8f0c8
6
+ metadata.gz: b226b3a68c6e81ddf17ff22577ffd80cae2b58201b18a38bae681b0729e531769426e3f760694d36121e1885a6dfc21383a91c4fe5664203aafb58ad8c00c0fd
7
+ data.tar.gz: 6bdda04f1ba31689656896323098be6e43e34c88cec3ea7922c6e0c55c6d8bc3b593f89ea863fcefb8a537da2ae38e6a2ebf159008e44e5d475cc025014fe80d
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ 0.0.5 (2016-03-09)
2
+ ==================
3
+ - Add: Support MapReduce executor
4
+ - https://github.com/civitaspo/embulk-output-sftp/pull/8
5
+ - Fix: Use ConfigException instead of RuntimeException
6
+ - https://github.com/civitaspo/embulk-output-sftp/pull/9/files
7
+ - Fix: Check to exist parent directory before uploading files
8
+ - https://github.com/civitaspo/embulk-output-sftp/pull/13
9
+ - Add: Support proxy settings
10
+ - https://github.com/civitaspo/embulk-output-sftp/pull/11
data/README.md CHANGED
@@ -14,10 +14,10 @@ Stores files on a SFTP Server
14
14
  ## Configuration
15
15
 
16
16
  - **host**: (string, required)
17
- - **port**: (string, default: `22`)
17
+ - **port**: (int, default: `22`)
18
18
  - **user**: (string, required)
19
19
  - **password**: (string, default: `null`)
20
- - **secret_key_file**: (string, default: `null`)
20
+ - **secret_key_file**: (string, default: `null`) [see below](#secret-keyfile-configuration)
21
21
  - **secret_key_passphrase**: (string, default: `""`)
22
22
  - **user_directory_is_root**: (boolean, default: `true`)
23
23
  - **timeout**: sftp connection timeout seconds (integer, default: `600`)
@@ -25,6 +25,19 @@ Stores files on a SFTP Server
25
25
  - **file_ext**: Extension of output files (string, required)
26
26
  - **sequence_format**: Format for sequence part of output files (string, default: `".%03d.%02d"`)
27
27
 
28
+ ### Proxy configuration
29
+
30
+ - **proxy**:
31
+ - **type**: (string(http | socks | stream), required, default: `null`)
32
+ - **http**: use HTTP Proxy
33
+ - **socks**: use SOCKS Proxy
34
+ - **stream**: Connects to the SFTP server through a remote host reached by SSH
35
+ - **host**: (string, required)
36
+ - **port**: (int, default: `22`)
37
+ - **user**: (string, optional)
38
+ - **password**: (string, optional, default: `null`)
39
+ - **command**: (string, optional)
40
+
28
41
  ## Example
29
42
 
30
43
  ```yaml
@@ -42,6 +55,53 @@ out:
42
55
  sequence_format: ".%01d%01d"
43
56
  ```
44
57
 
58
+ With proxy
59
+ ```yaml
60
+ out:
61
+ type: sftp
62
+ host: 127.0.0.1
63
+ port: 22
64
+ user: embulk
65
+ secret_key_file: /Users/embulk/.ssh/id_rsa
66
+ secret_key_passphrase: secret_pass
67
+ user_directory_is_root: false
68
+ timeout: 600
69
+ path_prefix: /data/sftp
70
+ proxy:
71
+ type: http
72
+ host: proxy_host
73
+ port: 8080
74
+ user: proxy_user
75
+ password: proxy_secret_pass
76
+ command:
77
+ ```
78
+
79
+ ### Secret Keyfile configuration
80
+
81
+ Please set path of secret_key_file as follows.
82
+ ```yaml
83
+ out:
84
+ type: sftp
85
+ ...
86
+ secret_key_file: /path/to/id_rsa
87
+ ...
88
+ ```
89
+
90
+ You can also embed contents of secret_key_file at config.yml.
91
+ ```yaml
92
+ out:
93
+ type: sftp
94
+ ...
95
+ secret_key_file:
96
+ content |
97
+ -----BEGIN RSA PRIVATE KEY-----
98
+ ABCDEFG...
99
+ HIJKLMN...
100
+ OPQRSTU...
101
+ -----END RSA PRIVATE KEY-----
102
+ ...
103
+ ```
104
+
45
105
  ## Run Example
46
106
  replace settings in `example/sample.yml` before running.
47
107
 
@@ -59,3 +119,7 @@ $ ./gradlew gem # -t to watch change of files and rebuild continuously
59
119
  ## Note
60
120
 
61
121
  This plugin uses "org.apache.commons:commons-vfs" and the library uses the logger "org.apache.commons.logging.Log". So, this plugin suppress the logger's message except when embulk log level is debug.
122
+
123
+ ## Contributors
124
+ - Satoshi Akama (@sakama)
125
+ - Rudolph Miller (@Rudolph-Miller)
data/build.gradle CHANGED
@@ -4,6 +4,7 @@ plugins {
4
4
  id "com.github.kt3k.coveralls" version "2.4.0"
5
5
  id "jacoco"
6
6
  id "java"
7
+ id "checkstyle"
7
8
  }
8
9
  import com.github.jrubygradle.JRubyExec
9
10
  repositories {
@@ -14,20 +15,22 @@ configurations {
14
15
  provided
15
16
  }
16
17
 
17
- version = "0.0.4"
18
+ version = "0.0.5"
18
19
  sourceCompatibility = 1.7
19
20
  targetCompatibility = 1.7
20
21
 
21
22
  dependencies {
22
- compile "org.embulk:embulk-core:0.7.+"
23
- provided "org.embulk:embulk-core:0.7.+"
23
+ compile "org.embulk:embulk-core:0.8.6"
24
+ provided "org.embulk:embulk-core:0.8.6"
24
25
  // compile "YOUR_JAR_DEPENDENCY_GROUP:YOUR_JAR_DEPENDENCY_MODULE:YOUR_JAR_DEPENDENCY_VERSION"
25
26
  compile "org.apache.commons:commons-vfs2:2.+"
26
27
  compile "com.jcraft:jsch:0.1.53"
27
28
  testCompile "junit:junit:4.+"
28
- testCompile "org.embulk:embulk-core:0.7.+:tests"
29
- testCompile "org.embulk:embulk-standards:0.7.+"
30
- testCompile "org.apache.sshd:apache-sshd:1.+"
29
+ testCompile "org.embulk:embulk-core:0.8.6:tests"
30
+ testCompile "org.embulk:embulk-standards:0.8.6"
31
+ testCompile "org.apache.sshd:apache-sshd:1.1.0+"
32
+ testCompile "org.littleshoot:littleproxy:1.1.0-beta1"
33
+ testCompile "io.netty:netty-all:4.0.34.Final"
31
34
  }
32
35
 
33
36
  jacocoTestReport {
@@ -44,6 +47,23 @@ task classpath(type: Copy, dependsOn: ["jar"]) {
44
47
  }
45
48
  clean { delete "classpath" }
46
49
 
50
+ checkstyle {
51
+ configFile = file("${project.rootDir}/config/checkstyle/checkstyle.xml")
52
+ toolVersion = '6.14.1'
53
+ }
54
+ checkstyleMain {
55
+ configFile = file("${project.rootDir}/config/checkstyle/default.xml")
56
+ ignoreFailures = true
57
+ }
58
+ checkstyleTest {
59
+ configFile = file("${project.rootDir}/config/checkstyle/default.xml")
60
+ ignoreFailures = true
61
+ }
62
+ task checkstyle(type: Checkstyle) {
63
+ classpath = sourceSets.main.output + sourceSets.test.output
64
+ source = sourceSets.main.allJava + sourceSets.test.allJava
65
+ }
66
+
47
67
  task gem(type: JRubyExec, dependsOn: ["gemspec", "classpath"]) {
48
68
  jrubyArgs "-rrubygems/gem_runner", "-eGem::GemRunner.new.run(ARGV)", "build"
49
69
  script "${project.name}.gemspec"
@@ -0,0 +1,128 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE module PUBLIC
3
+ "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
4
+ "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
5
+ <module name="Checker">
6
+ <!-- https://github.com/facebook/presto/blob/master/src/checkstyle/checks.xml -->
7
+ <module name="FileTabCharacter"/>
8
+ <module name="NewlineAtEndOfFile">
9
+ <property name="lineSeparator" value="lf"/>
10
+ </module>
11
+ <module name="RegexpMultiline">
12
+ <property name="format" value="\r"/>
13
+ <property name="message" value="Line contains carriage return"/>
14
+ </module>
15
+ <module name="RegexpMultiline">
16
+ <property name="format" value=" \n"/>
17
+ <property name="message" value="Line has trailing whitespace"/>
18
+ </module>
19
+ <module name="RegexpMultiline">
20
+ <property name="format" value="\{\n\n"/>
21
+ <property name="message" value="Blank line after opening brace"/>
22
+ </module>
23
+ <module name="RegexpMultiline">
24
+ <property name="format" value="\n\n\s*\}"/>
25
+ <property name="message" value="Blank line before closing brace"/>
26
+ </module>
27
+ <module name="RegexpMultiline">
28
+ <property name="format" value="\n\n\n"/>
29
+ <property name="message" value="Multiple consecutive blank lines"/>
30
+ </module>
31
+ <module name="RegexpMultiline">
32
+ <property name="format" value="\n\n\Z"/>
33
+ <property name="message" value="Blank line before end of file"/>
34
+ </module>
35
+ <module name="RegexpMultiline">
36
+ <property name="format" value="Preconditions\.checkNotNull"/>
37
+ <property name="message" value="Use of checkNotNull"/>
38
+ </module>
39
+
40
+ <module name="TreeWalker">
41
+ <module name="EmptyBlock">
42
+ <property name="option" value="text"/>
43
+ <property name="tokens" value="
44
+ LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF,
45
+ LITERAL_FOR, LITERAL_TRY, LITERAL_WHILE, INSTANCE_INIT, STATIC_INIT"/>
46
+ </module>
47
+ <module name="EmptyStatement"/>
48
+ <module name="EmptyForInitializerPad"/>
49
+ <module name="EmptyForIteratorPad">
50
+ <property name="option" value="space"/>
51
+ </module>
52
+ <module name="MethodParamPad">
53
+ <property name="allowLineBreaks" value="true"/>
54
+ <property name="option" value="nospace"/>
55
+ </module>
56
+ <module name="ParenPad"/>
57
+ <module name="TypecastParenPad"/>
58
+ <module name="NeedBraces"/>
59
+ <module name="LeftCurly">
60
+ <property name="option" value="nl"/>
61
+ <property name="tokens" value="CLASS_DEF, CTOR_DEF, INTERFACE_DEF, METHOD_DEF"/>
62
+ </module>
63
+ <module name="LeftCurly">
64
+ <property name="option" value="eol"/>
65
+ <property name="tokens" value="
66
+ LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR,
67
+ LITERAL_IF, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE"/>
68
+ </module>
69
+ <module name="RightCurly">
70
+ <property name="option" value="alone"/>
71
+ </module>
72
+ <module name="GenericWhitespace"/>
73
+ <module name="WhitespaceAfter"/>
74
+ <module name="NoWhitespaceBefore"/>
75
+
76
+ <module name="UpperEll"/>
77
+ <module name="DefaultComesLast"/>
78
+ <module name="ArrayTypeStyle"/>
79
+ <module name="MultipleVariableDeclarations"/>
80
+ <module name="ModifierOrder"/>
81
+ <module name="OneStatementPerLine"/>
82
+ <module name="StringLiteralEquality"/>
83
+ <module name="MutableException"/>
84
+ <module name="EqualsHashCode"/>
85
+ <module name="InnerAssignment"/>
86
+ <module name="InterfaceIsType"/>
87
+ <module name="HideUtilityClassConstructor"/>
88
+
89
+ <module name="MemberName"/>
90
+ <module name="LocalVariableName"/>
91
+ <module name="LocalFinalVariableName"/>
92
+ <module name="TypeName"/>
93
+ <module name="PackageName"/>
94
+ <module name="ParameterName"/>
95
+ <module name="StaticVariableName"/>
96
+ <module name="ClassTypeParameterName">
97
+ <property name="format" value="^[A-Z][0-9]?$"/>
98
+ </module>
99
+ <module name="MethodTypeParameterName">
100
+ <property name="format" value="^[A-Z][0-9]?$"/>
101
+ </module>
102
+
103
+ <module name="AvoidStarImport"/>
104
+ <module name="RedundantImport"/>
105
+ <module name="UnusedImports"/>
106
+ <module name="ImportOrder">
107
+ <property name="groups" value="*,javax,java"/>
108
+ <property name="separated" value="true"/>
109
+ <property name="option" value="bottom"/>
110
+ <property name="sortStaticImportsAlphabetically" value="true"/>
111
+ </module>
112
+
113
+ <module name="WhitespaceAround">
114
+ <property name="allowEmptyConstructors" value="true"/>
115
+ <property name="allowEmptyMethods" value="true"/>
116
+ <property name="ignoreEnhancedForColon" value="false"/>
117
+ <property name="tokens" value="
118
+ ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN,
119
+ BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE,
120
+ LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
121
+ LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
122
+ LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE,
123
+ LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL,
124
+ PLUS, PLUS_ASSIGN, QUESTION, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN,
125
+ STAR, STAR_ASSIGN, TYPE_EXTENSION_AND"/>
126
+ </module>
127
+ </module>
128
+ </module>
@@ -0,0 +1,108 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE module PUBLIC
3
+ "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
4
+ "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
5
+ <!--
6
+ This is a subset of ./checkstyle.xml which allows some loose styles
7
+ -->
8
+ <module name="Checker">
9
+ <module name="FileTabCharacter"/>
10
+ <module name="NewlineAtEndOfFile">
11
+ <property name="lineSeparator" value="lf"/>
12
+ </module>
13
+ <module name="RegexpMultiline">
14
+ <property name="format" value="\r"/>
15
+ <property name="message" value="Line contains carriage return"/>
16
+ </module>
17
+ <module name="RegexpMultiline">
18
+ <property name="format" value=" \n"/>
19
+ <property name="message" value="Line has trailing whitespace"/>
20
+ </module>
21
+ <module name="RegexpMultiline">
22
+ <property name="format" value="\n\n\n"/>
23
+ <property name="message" value="Multiple consecutive blank lines"/>
24
+ </module>
25
+ <module name="RegexpMultiline">
26
+ <property name="format" value="\n\n\Z"/>
27
+ <property name="message" value="Blank line before end of file"/>
28
+ </module>
29
+
30
+ <module name="TreeWalker">
31
+ <module name="EmptyBlock">
32
+ <property name="option" value="text"/>
33
+ <property name="tokens" value="
34
+ LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF,
35
+ LITERAL_FOR, LITERAL_TRY, LITERAL_WHILE, INSTANCE_INIT, STATIC_INIT"/>
36
+ </module>
37
+ <module name="EmptyStatement"/>
38
+ <module name="EmptyForInitializerPad"/>
39
+ <module name="EmptyForIteratorPad">
40
+ <property name="option" value="space"/>
41
+ </module>
42
+ <module name="MethodParamPad">
43
+ <property name="allowLineBreaks" value="true"/>
44
+ <property name="option" value="nospace"/>
45
+ </module>
46
+ <module name="ParenPad"/>
47
+ <module name="TypecastParenPad"/>
48
+ <module name="NeedBraces"/>
49
+ <module name="LeftCurly">
50
+ <property name="option" value="nl"/>
51
+ <property name="tokens" value="CLASS_DEF, CTOR_DEF, INTERFACE_DEF, METHOD_DEF"/>
52
+ </module>
53
+ <module name="LeftCurly">
54
+ <property name="option" value="eol"/>
55
+ <property name="tokens" value="
56
+ LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR,
57
+ LITERAL_IF, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE"/>
58
+ </module>
59
+ <module name="RightCurly">
60
+ <property name="option" value="alone"/>
61
+ </module>
62
+ <module name="GenericWhitespace"/>
63
+ <module name="WhitespaceAfter"/>
64
+ <module name="NoWhitespaceBefore"/>
65
+
66
+ <module name="UpperEll"/>
67
+ <module name="DefaultComesLast"/>
68
+ <module name="ArrayTypeStyle"/>
69
+ <module name="MultipleVariableDeclarations"/>
70
+ <module name="ModifierOrder"/>
71
+ <module name="OneStatementPerLine"/>
72
+ <module name="StringLiteralEquality"/>
73
+ <module name="MutableException"/>
74
+ <module name="EqualsHashCode"/>
75
+ <module name="InnerAssignment"/>
76
+ <module name="InterfaceIsType"/>
77
+ <module name="HideUtilityClassConstructor"/>
78
+
79
+ <module name="MemberName"/>
80
+ <module name="LocalVariableName"/>
81
+ <module name="LocalFinalVariableName"/>
82
+ <module name="TypeName"/>
83
+ <module name="PackageName"/>
84
+ <module name="ParameterName"/>
85
+ <module name="StaticVariableName"/>
86
+ <module name="ClassTypeParameterName">
87
+ <property name="format" value="^[A-Z][0-9]?$"/>
88
+ </module>
89
+ <module name="MethodTypeParameterName">
90
+ <property name="format" value="^[A-Z][0-9]?$"/>
91
+ </module>
92
+
93
+ <module name="WhitespaceAround">
94
+ <property name="allowEmptyConstructors" value="true"/>
95
+ <property name="allowEmptyMethods" value="true"/>
96
+ <property name="ignoreEnhancedForColon" value="false"/>
97
+ <property name="tokens" value="
98
+ ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN,
99
+ BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE,
100
+ LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
101
+ LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
102
+ LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE,
103
+ LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL,
104
+ PLUS, PLUS_ASSIGN, QUESTION, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN,
105
+ STAR, STAR_ASSIGN, TYPE_EXTENSION_AND"/>
106
+ </module>
107
+ </module>
108
+ </module>
Binary file
@@ -1,6 +1,6 @@
1
- #Tue Aug 11 00:26:20 PDT 2015
1
+ #Wed Jan 13 12:41:02 JST 2016
2
2
  distributionBase=GRADLE_USER_HOME
3
3
  distributionPath=wrapper/dists
4
4
  zipStoreBase=GRADLE_USER_HOME
5
5
  zipStorePath=wrapper/dists
6
- distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip
6
+ distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
@@ -0,0 +1,85 @@
1
+ package org.embulk.output.sftp;
2
+
3
+ import com.fasterxml.jackson.annotation.JsonCreator;
4
+ import com.fasterxml.jackson.annotation.JsonValue;
5
+ import com.google.common.base.Optional;
6
+ import org.apache.commons.vfs2.FileSystemOptions;
7
+ import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
8
+ import org.embulk.config.Config;
9
+ import org.embulk.config.ConfigDefault;
10
+ import org.embulk.config.ConfigException;
11
+ import org.embulk.config.Task;
12
+
13
+ import java.util.Locale;
14
+
15
+ interface ProxyTask
16
+ extends Task
17
+ {
18
+ @Config("type")
19
+ public ProxyType getType();
20
+
21
+ @Config("host")
22
+ public Optional<String> getHost();
23
+
24
+ @Config("user")
25
+ @ConfigDefault("null")
26
+ public Optional<String> getUser();
27
+
28
+ @Config("password")
29
+ @ConfigDefault("null")
30
+ public Optional<String> getPassword();
31
+
32
+ @Config("port")
33
+ @ConfigDefault("22")
34
+ public int getPort();
35
+
36
+ @Config("command")
37
+ @ConfigDefault("null")
38
+ public Optional<String> getCommand();
39
+
40
+ public enum ProxyType
41
+ {
42
+ HTTP,
43
+ SOCKS,
44
+ STREAM;
45
+
46
+ @JsonValue
47
+ @Override
48
+ public String toString()
49
+ {
50
+ return name().toLowerCase(Locale.ENGLISH);
51
+ }
52
+
53
+ @JsonCreator
54
+ public static ProxyType fromString(String value)
55
+ {
56
+ switch (value) {
57
+ case "http":
58
+ return HTTP;
59
+ case "socks":
60
+ return SOCKS;
61
+ case "stream":
62
+ return STREAM;
63
+ default:
64
+ throw new ConfigException(String.format("Unknown proxy type '%s'. Supported proxy types are http, socks, stream", value));
65
+ }
66
+ }
67
+
68
+ public static SftpFileSystemConfigBuilder setProxyType(SftpFileSystemConfigBuilder builder, FileSystemOptions fsOptions, ProxyTask.ProxyType type)
69
+ {
70
+ SftpFileSystemConfigBuilder.ProxyType setType = null;
71
+ switch (type) {
72
+ case HTTP:
73
+ setType = SftpFileSystemConfigBuilder.PROXY_HTTP;
74
+ break;
75
+ case SOCKS:
76
+ setType = SftpFileSystemConfigBuilder.PROXY_SOCKS5;
77
+ break;
78
+ case STREAM:
79
+ setType = SftpFileSystemConfigBuilder.PROXY_STREAM;
80
+ }
81
+ builder.setProxyType(fsOptions, setType);
82
+ return builder;
83
+ }
84
+ }
85
+ }
@@ -1,5 +1,6 @@
1
1
  package org.embulk.output.sftp;
2
2
 
3
+ import com.google.common.base.Function;
3
4
  import com.google.common.base.Throwables;
4
5
  import org.apache.commons.vfs2.FileObject;
5
6
  import org.apache.commons.vfs2.FileSystemException;
@@ -7,11 +8,13 @@ import org.apache.commons.vfs2.FileSystemOptions;
7
8
  import org.apache.commons.vfs2.impl.StandardFileSystemManager;
8
9
  import org.apache.commons.vfs2.provider.sftp.IdentityInfo;
9
10
  import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
11
+ import org.embulk.config.ConfigException;
10
12
  import org.embulk.config.TaskReport;
11
13
  import org.embulk.spi.Buffer;
12
14
  import org.embulk.spi.Exec;
13
15
  import org.embulk.spi.FileOutput;
14
16
  import org.embulk.spi.TransactionalFileOutput;
17
+ import org.embulk.spi.unit.LocalFile;
15
18
  import org.slf4j.Logger;
16
19
 
17
20
  import java.io.File;
@@ -56,7 +59,7 @@ public class SftpFileOutput
56
59
  }
57
60
  catch (FileSystemException e) {
58
61
  logger.error(e.getMessage());
59
- throw new RuntimeException(e);
62
+ throw new ConfigException(e);
60
63
  }
61
64
 
62
65
  return manager;
@@ -76,18 +79,45 @@ public class SftpFileOutput
76
79
  FileSystemOptions fsOptions = new FileSystemOptions();
77
80
 
78
81
  try {
79
- SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(fsOptions, task.getUserDirIsRoot());
80
- SftpFileSystemConfigBuilder.getInstance().setTimeout(fsOptions, task.getSftpConnectionTimeout());
81
- SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fsOptions, "no");
82
+ SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance();
83
+ builder.setUserDirIsRoot(fsOptions, task.getUserDirIsRoot());
84
+ builder.setTimeout(fsOptions, task.getSftpConnectionTimeout());
85
+ builder.setStrictHostKeyChecking(fsOptions, "no");
82
86
  if (task.getSecretKeyFilePath().isPresent()) {
83
- IdentityInfo identityInfo = new IdentityInfo(new File((task.getSecretKeyFilePath().get())), task.getSecretKeyPassphrase().getBytes());
84
- SftpFileSystemConfigBuilder.getInstance().setIdentityInfo(fsOptions, identityInfo);
87
+ IdentityInfo identityInfo = new IdentityInfo(
88
+ new File((task.getSecretKeyFilePath().transform(localFileToPathString()).get())),
89
+ task.getSecretKeyPassphrase().getBytes()
90
+ );
91
+ builder.setIdentityInfo(fsOptions, identityInfo);
85
92
  logger.info("set identity: {}", task.getSecretKeyFilePath().get());
86
93
  }
94
+
95
+ if (task.getProxy().isPresent()) {
96
+ ProxyTask proxy = task.getProxy().get();
97
+
98
+ ProxyTask.ProxyType.setProxyType(builder, fsOptions, proxy.getType());
99
+
100
+ if (proxy.getHost().isPresent()) {
101
+ builder.setProxyHost(fsOptions, proxy.getHost().get());
102
+ builder.setProxyPort(fsOptions, proxy.getPort());
103
+ }
104
+
105
+ if (proxy.getUser().isPresent()) {
106
+ builder.setProxyUser(fsOptions, proxy.getUser().get());
107
+ }
108
+
109
+ if (proxy.getPassword().isPresent()) {
110
+ builder.setProxyPassword(fsOptions, proxy.getPassword().get());
111
+ }
112
+
113
+ if (proxy.getCommand().isPresent()) {
114
+ builder.setProxyCommand(fsOptions, proxy.getCommand().get());
115
+ }
116
+ }
87
117
  }
88
118
  catch (FileSystemException e) {
89
119
  logger.error(e.getMessage());
90
- throw new RuntimeException(e);
120
+ throw new ConfigException(e);
91
121
  }
92
122
 
93
123
  return fsOptions;
@@ -137,7 +167,9 @@ public class SftpFileOutput
137
167
  logger.error(e.getMessage());
138
168
  Throwables.propagate(e);
139
169
  }
140
- buffer.release();
170
+ finally {
171
+ buffer.release();
172
+ }
141
173
  }
142
174
 
143
175
  @Override
@@ -161,10 +193,9 @@ public class SftpFileOutput
161
193
  @Override
162
194
  public TaskReport commit()
163
195
  {
164
- return null;
196
+ return Exec.newTaskReport();
165
197
  }
166
198
 
167
-
168
199
  private void closeCurrentFile()
169
200
  {
170
201
  if (currentFile == null) {
@@ -194,7 +225,7 @@ public class SftpFileOutput
194
225
  }
195
226
  catch (URISyntaxException e) {
196
227
  logger.error(e.getMessage());
197
- throw new RuntimeException(e);
228
+ throw new ConfigException(e);
198
229
  }
199
230
  }
200
231
 
@@ -209,7 +240,15 @@ public class SftpFileOutput
209
240
  int count = 0;
210
241
  while (true) {
211
242
  try {
212
- return manager.resolveFile(sftpUri.toString(), fsOptions);
243
+ FileObject file = manager.resolveFile(sftpUri.toString(), fsOptions);
244
+ if (file.getParent().exists()) {
245
+ logger.info("parent directory {} exists there", file.getParent());
246
+ return file;
247
+ }
248
+ else {
249
+ logger.info("trying to create parent directory {}", file.getParent());
250
+ file.getParent().createFolder();
251
+ }
213
252
  }
214
253
  catch (FileSystemException e) {
215
254
  if (++count == maxConnectionRetry) {
@@ -230,4 +269,15 @@ public class SftpFileOutput
230
269
  }
231
270
  }
232
271
  }
272
+
273
+ private Function<LocalFile, String> localFileToPathString()
274
+ {
275
+ return new Function<LocalFile, String>()
276
+ {
277
+ public String apply(LocalFile file)
278
+ {
279
+ return file.getPath().toString();
280
+ }
281
+ };
282
+ }
233
283
  }
@@ -11,6 +11,7 @@ import org.embulk.config.TaskSource;
11
11
  import org.embulk.spi.Exec;
12
12
  import org.embulk.spi.FileOutputPlugin;
13
13
  import org.embulk.spi.TransactionalFileOutput;
14
+ import org.embulk.spi.unit.LocalFile;
14
15
  import org.slf4j.Logger;
15
16
 
16
17
  import java.util.List;
@@ -39,7 +40,8 @@ public class SftpFileOutputPlugin
39
40
 
40
41
  @Config("secret_key_file")
41
42
  @ConfigDefault("null")
42
- public Optional<String> getSecretKeyFilePath();
43
+ public Optional<LocalFile> getSecretKeyFilePath();
44
+ public void setSecretKeyFilePath(Optional<LocalFile> secretKeyFilePath);
43
45
 
44
46
  @Config("secret_key_passphrase")
45
47
  @ConfigDefault("\"\"")
@@ -67,6 +69,9 @@ public class SftpFileOutputPlugin
67
69
  @ConfigDefault("\"%03d.%02d.\"")
68
70
  public String getSequenceFormat();
69
71
 
72
+ @Config("proxy")
73
+ @ConfigDefault("null")
74
+ public Optional<ProxyTask> getProxy();
70
75
  }
71
76
 
72
77
  @Override
@@ -2,8 +2,6 @@ package org.embulk.output.sftp;
2
2
 
3
3
  import com.google.common.base.Charsets;
4
4
  import com.google.common.base.Optional;
5
- import com.google.common.base.Splitter;
6
- import com.google.common.base.Throwables;
7
5
  import com.google.common.collect.Lists;
8
6
  import com.google.common.io.Resources;
9
7
  import org.apache.commons.vfs2.FileSystemException;
@@ -13,11 +11,12 @@ import org.apache.sshd.server.Command;
13
11
  import org.apache.sshd.server.SshServer;
14
12
  import org.apache.sshd.server.auth.password.PasswordAuthenticator;
15
13
  import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
16
- import org.apache.sshd.server.command.ScpCommandFactory;
17
14
  import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
15
+ import org.apache.sshd.server.scp.ScpCommandFactory;
18
16
  import org.apache.sshd.server.session.ServerSession;
19
17
  import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
20
18
  import org.embulk.EmbulkTestRuntime;
19
+ import org.embulk.config.ConfigException;
21
20
  import org.embulk.config.ConfigLoader;
22
21
  import org.embulk.config.ConfigSource;
23
22
  import org.embulk.config.TaskReport;
@@ -32,37 +31,39 @@ import org.embulk.spi.Schema;
32
31
  import org.embulk.spi.TransactionalPageOutput;
33
32
  import org.embulk.spi.time.Timestamp;
34
33
  import org.hamcrest.CoreMatchers;
35
- import org.hamcrest.Matcher;
36
34
  import org.junit.After;
37
35
  import org.junit.Before;
38
36
  import org.junit.Rule;
39
37
  import org.junit.Test;
40
38
  import org.junit.rules.ExpectedException;
41
39
  import org.junit.rules.TemporaryFolder;
40
+ import org.littleshoot.proxy.HttpProxyServer;
41
+ import org.littleshoot.proxy.impl.DefaultHttpProxyServer;
42
42
  import org.slf4j.Logger;
43
43
 
44
44
  import java.io.File;
45
45
  import java.io.IOException;
46
46
  import java.nio.file.DirectoryStream;
47
- import java.nio.file.FileSystems;
48
47
  import java.nio.file.Files;
49
48
  import java.nio.file.Path;
50
- import java.nio.file.PathMatcher;
51
49
  import java.nio.file.Paths;
52
50
  import java.security.PublicKey;
53
- import java.util.Arrays;
54
51
  import java.util.Collections;
55
52
  import java.util.List;
56
53
 
57
54
  import static com.google.common.io.Files.readLines;
58
- import static org.embulk.spi.type.Types.*;
55
+ import static org.embulk.spi.type.Types.BOOLEAN;
56
+ import static org.embulk.spi.type.Types.DOUBLE;
57
+ import static org.embulk.spi.type.Types.JSON;
58
+ import static org.embulk.spi.type.Types.LONG;
59
+ import static org.embulk.spi.type.Types.STRING;
60
+ import static org.embulk.spi.type.Types.TIMESTAMP;
59
61
  import static org.hamcrest.CoreMatchers.containsString;
60
62
  import static org.hamcrest.CoreMatchers.hasItem;
61
- import static org.hamcrest.CoreMatchers.instanceOf;
62
- import static org.hamcrest.MatcherAssert.*;
63
- import static org.hamcrest.core.Is.is;
64
63
  import static org.junit.Assert.assertEquals;
65
- //import static org.hamcrest.Matchers.*;
64
+ import static org.junit.Assert.assertThat;
65
+ import static org.msgpack.value.ValueFactory.newMap;
66
+ import static org.msgpack.value.ValueFactory.newString;
66
67
 
67
68
  public class TestSftpFileOutputPlugin
68
69
  {
@@ -80,6 +81,8 @@ public class TestSftpFileOutputPlugin
80
81
  private SshServer sshServer;
81
82
  private static final String HOST = "127.0.0.1";
82
83
  private static final int PORT = 20022;
84
+ private static final String PROXY_HOST = "127.0.0.1";
85
+ private static final int PROXY_PORT = 8080;
83
86
  private static final String USERNAME = "username";
84
87
  private static final String PASSWORD = "password";
85
88
  private static final String SECRET_KEY_FILE = Resources.getResource("id_rsa").getPath();
@@ -90,6 +93,7 @@ public class TestSftpFileOutputPlugin
90
93
  .add("_c2", DOUBLE)
91
94
  .add("_c3", STRING)
92
95
  .add("_c4", TIMESTAMP)
96
+ .add("_c5", JSON)
93
97
  .build();
94
98
 
95
99
  @Before
@@ -100,13 +104,18 @@ public class TestSftpFileOutputPlugin
100
104
  SftpFileOutputPlugin sftpFileOutputPlugin = new SftpFileOutputPlugin();
101
105
  runner = new FileOutputRunner(sftpFileOutputPlugin);
102
106
 
107
+ sshServer = createSshServer(HOST, PORT, USERNAME, PASSWORD);
108
+ }
109
+
110
+ private SshServer createSshServer(String host, int port, final String sshUsername, final String sshPassword)
111
+ {
103
112
  // setup a mock sftp server
104
- sshServer = SshServer.setUpDefaultServer();
113
+ SshServer sshServer = SshServer.setUpDefaultServer();
105
114
  VirtualFileSystemFactory fsFactory = new VirtualFileSystemFactory();
106
- fsFactory.setUserHomeDir(USERNAME, testFolder.getRoot().getAbsolutePath());
115
+ fsFactory.setUserHomeDir(sshUsername, testFolder.getRoot().toPath());
107
116
  sshServer.setFileSystemFactory(fsFactory);
108
- sshServer.setHost(HOST);
109
- sshServer.setPort(PORT);
117
+ sshServer.setHost(host);
118
+ sshServer.setPort(port);
110
119
  sshServer.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
111
120
  sshServer.setCommandFactory(new ScpCommandFactory());
112
121
  sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
@@ -115,7 +124,7 @@ public class TestSftpFileOutputPlugin
115
124
  @Override
116
125
  public boolean authenticate(final String username, final String password, final ServerSession session)
117
126
  {
118
- return USERNAME.contentEquals(username) && PASSWORD.contentEquals(password);
127
+ return sshUsername.contentEquals(username) && sshPassword.contentEquals(password);
119
128
  }
120
129
  });
121
130
  sshServer.setPublickeyAuthenticator(new PublickeyAuthenticator()
@@ -133,10 +142,19 @@ public class TestSftpFileOutputPlugin
133
142
  catch (IOException e) {
134
143
  logger.debug(e.getMessage(), e);
135
144
  }
145
+ return sshServer;
146
+ }
147
+
148
+ private HttpProxyServer createProxyServer(int port)
149
+ {
150
+ return DefaultHttpProxyServer.bootstrap()
151
+ .withPort(port)
152
+ .start();
136
153
  }
137
154
 
138
155
  @After
139
- public void cleanup() throws InterruptedException {
156
+ public void cleanup() throws InterruptedException
157
+ {
140
158
  try {
141
159
  sshServer.stop(true);
142
160
  }
@@ -151,17 +169,19 @@ public class TestSftpFileOutputPlugin
151
169
  return loader.fromYamlString(yaml);
152
170
  }
153
171
 
154
- private List<String> lsR(List<String> fileNames, Path dir) {
172
+ private List<String> lsR(List<String> fileNames, Path dir)
173
+ {
155
174
  try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
156
175
  for (Path path : stream) {
157
- if(path.toFile().isDirectory()) {
176
+ if (path.toFile().isDirectory()) {
158
177
  lsR(fileNames, path);
159
- } else {
178
+ }
179
+ else {
160
180
  fileNames.add(path.toAbsolutePath().toString());
161
181
  }
162
182
  }
163
183
  }
164
- catch(IOException e) {
184
+ catch (IOException e) {
165
185
  logger.debug(e.getMessage(), e);
166
186
  }
167
187
  return fileNames;
@@ -179,12 +199,12 @@ public class TestSftpFileOutputPlugin
179
199
  boolean committed = false;
180
200
  try {
181
201
  // Result:
182
- // _c0,_c1,_c2,_c3,_c4
183
- // true,2,3.0,45,1970-01-01 00:00:00.678000 +0000
184
- // true,2,3.0,45,1970-01-01 00:00:00.678000 +0000
185
- for (Page page : PageTestUtils.buildPage(runtime.getBufferAllocator(), SCHEMA, true, 2L, 3.0D, "45",
186
- Timestamp.ofEpochMilli(678L), true, 2L, 3.0D, "45",
187
- Timestamp.ofEpochMilli(678L))) {
202
+ // _c0,_c1,_c2,_c3,_c4,_c5
203
+ // true,2,3.0,45,1970-01-01 00:00:00.678000 +0000,{\"k\":\"v\"}
204
+ // true,2,3.0,45,1970-01-01 00:00:00.678000 +0000,{\"k\":\"v\"}
205
+ for (Page page : PageTestUtils.buildPage(runtime.getBufferAllocator(), SCHEMA,
206
+ true, 2L, 3.0D, "45", Timestamp.ofEpochMilli(678L), newMap(newString("k"), newString("v")),
207
+ true, 2L, 3.0D, "45", Timestamp.ofEpochMilli(678L), newMap(newString("k"), newString("v")))) {
188
208
  pageOutput.add(page);
189
209
  if (sleep.isPresent()) {
190
210
  Thread.sleep(sleep.get() * 1000);
@@ -215,7 +235,7 @@ public class TestSftpFileOutputPlugin
215
235
  for (int i = 0; i < lines.size(); i++) {
216
236
  String[] record = lines.get(i).split(",");
217
237
  if (i == 0) {
218
- for (int j = 0; j <= 4 ; j++) {
238
+ for (int j = 0; j <= 4; j++) {
219
239
  assertEquals("_c" + j, record[j]);
220
240
  }
221
241
  }
@@ -226,6 +246,7 @@ public class TestSftpFileOutputPlugin
226
246
  assertEquals("3.0", record[2]);
227
247
  assertEquals("45", record[3]);
228
248
  assertEquals("1970-01-01 00:00:00.678000 +0000", record[4]);
249
+ assertEquals("{\"k\":\"v\"}", record[5]);
229
250
  }
230
251
  }
231
252
  }
@@ -272,6 +293,49 @@ public class TestSftpFileOutputPlugin
272
293
  assertEquals(pathPrefix, task.getPathPrefix());
273
294
  assertEquals("txt", task.getFileNameExtension());
274
295
  assertEquals("%03d.%02d.", task.getSequenceFormat());
296
+ assertEquals(Optional.absent(), task.getProxy());
297
+ }
298
+
299
+ @Test
300
+ public void testConfigValuesIncludingProxy()
301
+ {
302
+ // setting embulk config
303
+ final String pathPrefix = "/test/testUserPassword";
304
+ String configYaml = "" +
305
+ "type: sftp\n" +
306
+ "host: " + HOST + "\n" +
307
+ "user: " + USERNAME + "\n" +
308
+ "path_prefix: " + pathPrefix + "\n" +
309
+ "file_ext: txt\n" +
310
+ "proxy: \n" +
311
+ " type: http\n" +
312
+ " host: proxy_host\n" +
313
+ " port: 80 \n" +
314
+ " user: proxy_user\n" +
315
+ " password: proxy_pass\n" +
316
+ " command: proxy_command\n" +
317
+ "formatter:\n" +
318
+ " type: csv\n" +
319
+ " newline: CRLF\n" +
320
+ " newline_in_field: LF\n" +
321
+ " header_line: true\n" +
322
+ " charset: UTF-8\n" +
323
+ " quote_policy: NONE\n" +
324
+ " quote: \"\\\"\"\n" +
325
+ " escape: \"\\\\\"\n" +
326
+ " null_string: \"\"\n" +
327
+ " default_timezone: 'UTC'";
328
+
329
+ ConfigSource config = getConfigFromYaml(configYaml);
330
+ PluginTask task = config.loadConfig(PluginTask.class);
331
+
332
+ ProxyTask proxy = task.getProxy().get();
333
+ assertEquals("proxy_command", proxy.getCommand().get());
334
+ assertEquals("proxy_host", proxy.getHost().get());
335
+ assertEquals("proxy_user", proxy.getUser().get());
336
+ assertEquals("proxy_pass", proxy.getPassword().get());
337
+ assertEquals(80, proxy.getPort());
338
+ assertEquals(ProxyTask.ProxyType.HTTP, proxy.getType());
275
339
  }
276
340
 
277
341
  // Cases
@@ -284,7 +348,6 @@ public class TestSftpFileOutputPlugin
284
348
  // timeout
285
349
  // 0 second
286
350
 
287
-
288
351
  @Test
289
352
  public void testUserPasswordAndPutToUserDirectoryRoot()
290
353
  {
@@ -318,7 +381,6 @@ public class TestSftpFileOutputPlugin
318
381
  assertRecordsInFile(String.format("%s/%s001.00.txt",
319
382
  testFolder.getRoot().getAbsolutePath(),
320
383
  pathPrefix));
321
-
322
384
  }
323
385
 
324
386
  @Test
@@ -358,6 +420,60 @@ public class TestSftpFileOutputPlugin
358
420
  pathPrefix));
359
421
  }
360
422
 
423
+ @Test
424
+ public void testUserSecretKeyFileWithProxy()
425
+ {
426
+ HttpProxyServer proxyServer = null;
427
+ try {
428
+ proxyServer = createProxyServer(PROXY_PORT);
429
+
430
+ // setting embulk config
431
+ final String pathPrefix = "/test/testUserPassword";
432
+ String configYaml = "" +
433
+ "type: sftp\n" +
434
+ "host: " + HOST + "\n" +
435
+ "port: " + PORT + "\n" +
436
+ "user: " + USERNAME + "\n" +
437
+ "secret_key_file: " + SECRET_KEY_FILE + "\n" +
438
+ "secret_key_passphrase: " + SECRET_KEY_PASSPHRASE + "\n" +
439
+ "path_prefix: " + testFolder.getRoot().getAbsolutePath() + pathPrefix + "\n" +
440
+ "file_ext: txt\n" +
441
+ "proxy: \n" +
442
+ " type: http\n" +
443
+ " host: " + PROXY_HOST + "\n" +
444
+ " port: " + PROXY_PORT + " \n" +
445
+ " user: " + USERNAME + "\n" +
446
+ " password: " + PASSWORD + "\n" +
447
+ " command: \n" +
448
+ "formatter:\n" +
449
+ " type: csv\n" +
450
+ " newline: CRLF\n" +
451
+ " newline_in_field: LF\n" +
452
+ " header_line: true\n" +
453
+ " charset: UTF-8\n" +
454
+ " quote_policy: NONE\n" +
455
+ " quote: \"\\\"\"\n" +
456
+ " escape: \"\\\\\"\n" +
457
+ " null_string: \"\"\n" +
458
+ " default_timezone: 'UTC'";
459
+
460
+ // runner.transaction -> ...
461
+ run(configYaml, Optional.<Integer>absent());
462
+
463
+ List<String> fileList = lsR(Lists.<String>newArrayList(), Paths.get(testFolder.getRoot().getAbsolutePath()));
464
+ assertThat(fileList, hasItem(containsString(pathPrefix + "001.00.txt")));
465
+
466
+ assertRecordsInFile(String.format("%s/%s001.00.txt",
467
+ testFolder.getRoot().getAbsolutePath(),
468
+ pathPrefix));
469
+ }
470
+ finally {
471
+ if (proxyServer != null) {
472
+ proxyServer.stop();
473
+ }
474
+ }
475
+ }
476
+
361
477
  @Test
362
478
  public void testTimeout()
363
479
  {
@@ -393,4 +509,30 @@ public class TestSftpFileOutputPlugin
393
509
  // runner.transaction -> ...
394
510
  run(configYaml, Optional.of(60)); // sleep 1 minute while processing
395
511
  }
512
+
513
+ @Test
514
+ public void testProxyType()
515
+ {
516
+ // test valueOf()
517
+ assertEquals("http", ProxyTask.ProxyType.valueOf("HTTP").toString());
518
+ assertEquals("socks", ProxyTask.ProxyType.valueOf("SOCKS").toString());
519
+ assertEquals("stream", ProxyTask.ProxyType.valueOf("STREAM").toString());
520
+ try {
521
+ ProxyTask.ProxyType.valueOf("non-existing-type");
522
+ }
523
+ catch (Exception e) {
524
+ assertEquals(IllegalArgumentException.class, e.getClass());
525
+ }
526
+
527
+ // test fromString
528
+ assertEquals(ProxyTask.ProxyType.HTTP, ProxyTask.ProxyType.fromString("http"));
529
+ assertEquals(ProxyTask.ProxyType.SOCKS, ProxyTask.ProxyType.fromString("socks"));
530
+ assertEquals(ProxyTask.ProxyType.STREAM, ProxyTask.ProxyType.fromString("stream"));
531
+ try {
532
+ ProxyTask.ProxyType.fromString("non-existing-type");
533
+ }
534
+ catch (Exception e) {
535
+ assertEquals(ConfigException.class, e.getClass());
536
+ }
537
+ }
396
538
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-output-sftp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Civitaspo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-28 00:00:00.000000000 Z
11
+ date: 2016-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -47,9 +47,12 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - .gitignore
49
49
  - .travis.yml
50
+ - CHANGELOG.md
50
51
  - LICENSE.txt
51
52
  - README.md
52
53
  - build.gradle
54
+ - config/checkstyle/checkstyle.xml
55
+ - config/checkstyle/default.xml
53
56
  - example/data.csv
54
57
  - example/sample.yml
55
58
  - gradle/wrapper/gradle-wrapper.jar
@@ -57,6 +60,7 @@ files:
57
60
  - gradlew
58
61
  - gradlew.bat
59
62
  - lib/embulk/output/sftp.rb
63
+ - src/main/java/org/embulk/output/sftp/ProxyTask.java
60
64
  - src/main/java/org/embulk/output/sftp/SftpFileOutput.java
61
65
  - src/main/java/org/embulk/output/sftp/SftpFileOutputPlugin.java
62
66
  - src/test/java/org/embulk/output/sftp/TestSftpFileOutputPlugin.java
@@ -64,7 +68,7 @@ files:
64
68
  - src/test/resources/id_rsa.pub
65
69
  - classpath/commons-logging-1.2.jar
66
70
  - classpath/commons-vfs2-2.1.1660580.2.jar
67
- - classpath/embulk-output-sftp-0.0.4.jar
71
+ - classpath/embulk-output-sftp-0.0.5.jar
68
72
  - classpath/jsch-0.1.53.jar
69
73
  homepage: https://github.com/civitaspo/embulk-output-sftp
70
74
  licenses:
Binary file