embulk-output-gcs 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f2569f6effb1c6cd11617f367c4f9edc5c34955
4
- data.tar.gz: a320b195255e974e5bc94872af9674930284bf11
3
+ metadata.gz: c5f66c9aebb242064e49a624cb08443142d7440b
4
+ data.tar.gz: bb3ef12c25a3bb768e2453012e351073566bf5b1
5
5
  SHA512:
6
- metadata.gz: d44045b96beeed143a690ce74d93463c35183f32114990a19b48d796f40180e32885014cebda5e2551e514fdbd5c2cf092d16d7ae251d7eb6515a796eaa902d2
7
- data.tar.gz: d32896f52c60f511eb5bcdb5c802219d4652e24f8722c2e4f85793f6aab415dc21204b588e9e1fe7e50175b5268d467c9f171e14df37cc3ad30167db67d19363
6
+ metadata.gz: 337c8a5c9cbf80008865a89dae91bad27de12915354b6937223ce72ef9f4295d089495ee577b2e29001486bb9cc1ff4217b23d1a7d7832bedaac9228ac3f224c
7
+ data.tar.gz: e26a507cebd8e93f87b0b5cd8b7c206901cc3ff9ca01b85a92e4ec721a2c84e164a009b134c259fb88a5e35ef8f02b47aaf2ebb9eab22d45948acb30cc2dadc4
data/build.gradle CHANGED
@@ -2,6 +2,7 @@ plugins {
2
2
  id "com.jfrog.bintray" version "1.1"
3
3
  id "com.github.jruby-gradle.base" version "0.1.5"
4
4
  id "java"
5
+ id "checkstyle"
5
6
  id "jacoco"
6
7
  }
7
8
  import com.github.jrubygradle.JRubyExec
@@ -16,18 +17,18 @@ configurations {
16
17
  sourceCompatibility = 1.7
17
18
  targetCompatibility = 1.7
18
19
 
19
- version = "0.3.0"
20
+ version = "0.4.0"
20
21
 
21
22
  dependencies {
22
- compile "org.embulk:embulk-core:0.7.3"
23
- provided "org.embulk:embulk-core:0.7.3"
23
+ compile "org.embulk:embulk-core:0.8.6"
24
+ provided "org.embulk:embulk-core:0.8.6"
24
25
 
25
26
  compile "com.google.http-client:google-http-client-jackson2:1.19.0"
26
27
  compile ("com.google.apis:google-api-services-storage:v1-rev28-1.19.1") {exclude module: "guava-jdk5"}
27
28
 
28
29
  testCompile "junit:junit:4.12"
29
- testCompile "org.embulk:embulk-core:0.7.5:tests"
30
- testCompile "org.embulk:embulk-standards:0.7.5"
30
+ testCompile "org.embulk:embulk-core:0.8.6:tests"
31
+ testCompile "org.embulk:embulk-standards:0.8.6"
31
32
  }
32
33
 
33
34
  task classpath(type: Copy, dependsOn: ["jar"]) {
@@ -37,6 +38,23 @@ task classpath(type: Copy, dependsOn: ["jar"]) {
37
38
  }
38
39
  clean { delete 'classpath' }
39
40
 
41
+ checkstyle {
42
+ configFile = file("${project.rootDir}/config/checkstyle/checkstyle.xml")
43
+ toolVersion = '6.14.1'
44
+ }
45
+ checkstyleMain {
46
+ configFile = file("${project.rootDir}/config/checkstyle/default.xml")
47
+ ignoreFailures = true
48
+ }
49
+ checkstyleTest {
50
+ configFile = file("${project.rootDir}/config/checkstyle/default.xml")
51
+ ignoreFailures = true
52
+ }
53
+ task checkstyle(type: Checkstyle) {
54
+ classpath = sourceSets.main.output + sourceSets.test.output
55
+ source = sourceSets.main.allJava + sourceSets.test.allJava
56
+ }
57
+
40
58
  task gem(type: JRubyExec, dependsOn: ["build", "gemspec", "classpath"]) {
41
59
  jrubyArgs "-rrubygems/gem_runner", "-eGem::GemRunner.new.run(ARGV)", "build"
42
60
  script "build/gemspec"
@@ -0,0 +1,130 @@
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
+ <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
97
+ </module>
98
+ <module name="ClassTypeParameterName">
99
+ <property name="format" value="^[A-Z][0-9]?$"/>
100
+ </module>
101
+ <module name="MethodTypeParameterName">
102
+ <property name="format" value="^[A-Z][0-9]?$"/>
103
+ </module>
104
+
105
+ <module name="AvoidStarImport"/>
106
+ <module name="RedundantImport"/>
107
+ <module name="UnusedImports"/>
108
+ <module name="ImportOrder">
109
+ <property name="groups" value="*,javax,java"/>
110
+ <property name="separated" value="true"/>
111
+ <property name="option" value="bottom"/>
112
+ <property name="sortStaticImportsAlphabetically" value="true"/>
113
+ </module>
114
+
115
+ <module name="WhitespaceAround">
116
+ <property name="allowEmptyConstructors" value="true"/>
117
+ <property name="allowEmptyMethods" value="true"/>
118
+ <property name="ignoreEnhancedForColon" value="false"/>
119
+ <property name="tokens" value="
120
+ ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN,
121
+ BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE,
122
+ LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
123
+ LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
124
+ LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE,
125
+ LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL,
126
+ PLUS, PLUS_ASSIGN, QUESTION, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN,
127
+ STAR, STAR_ASSIGN, TYPE_EXTENSION_AND"/>
128
+ </module>
129
+ </module>
130
+ </module>
@@ -0,0 +1,110 @@
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
+ <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
87
+ </module>
88
+ <module name="ClassTypeParameterName">
89
+ <property name="format" value="^[A-Z][0-9]?$"/>
90
+ </module>
91
+ <module name="MethodTypeParameterName">
92
+ <property name="format" value="^[A-Z][0-9]?$"/>
93
+ </module>
94
+
95
+ <module name="WhitespaceAround">
96
+ <property name="allowEmptyConstructors" value="true"/>
97
+ <property name="allowEmptyMethods" value="true"/>
98
+ <property name="ignoreEnhancedForColon" value="false"/>
99
+ <property name="tokens" value="
100
+ ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN,
101
+ BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE,
102
+ LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
103
+ LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
104
+ LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE,
105
+ LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL,
106
+ PLUS, PLUS_ASSIGN, QUESTION, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN,
107
+ STAR, STAR_ASSIGN, TYPE_EXTENSION_AND"/>
108
+ </module>
109
+ </module>
110
+ </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
@@ -1,110 +1,198 @@
1
1
  package org.embulk.output;
2
2
 
3
- import java.io.File;
4
- import java.io.FileInputStream;
5
- import java.io.IOException;
6
- import java.util.Collections;
7
- import com.google.api.client.http.apache.ApacheHttpTransport;
8
- import com.google.api.services.storage.model.Objects;
9
- import com.google.common.base.Optional;
10
- import com.google.common.collect.ImmutableList;
11
- import java.security.GeneralSecurityException;
3
+ import com.google.api.client.auth.oauth2.TokenResponseException;
12
4
  import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
13
5
  import com.google.api.client.googleapis.compute.ComputeCredential;
6
+ import com.google.api.client.googleapis.json.GoogleJsonResponseException;
7
+ import com.google.api.client.http.HttpRequestInitializer;
14
8
  import com.google.api.client.http.HttpTransport;
9
+ import com.google.api.client.http.apache.ApacheHttpTransport;
15
10
  import com.google.api.client.json.JsonFactory;
16
11
  import com.google.api.client.json.jackson2.JacksonFactory;
17
- import com.google.api.client.http.HttpRequestInitializer;
18
- import com.google.api.client.googleapis.json.GoogleJsonResponseException;
19
12
  import com.google.api.services.storage.Storage;
20
13
  import com.google.api.services.storage.StorageScopes;
14
+ import com.google.common.base.Optional;
15
+ import com.google.common.base.Throwables;
16
+ import com.google.common.collect.ImmutableList;
17
+ import org.embulk.config.ConfigException;
21
18
  import org.embulk.spi.Exec;
19
+ import org.embulk.spi.util.RetryExecutor.RetryGiveupException;
20
+ import org.embulk.spi.util.RetryExecutor.Retryable;
22
21
  import org.slf4j.Logger;
22
+ import static org.embulk.spi.util.RetryExecutor.retryExecutor;
23
+
24
+ import java.io.File;
25
+ import java.io.FileInputStream;
26
+
27
+ import java.io.IOException;
28
+ import java.io.InterruptedIOException;
29
+ import java.security.GeneralSecurityException;
30
+ import java.util.Collections;
23
31
 
24
32
  public class GcsAuthentication
25
33
  {
26
- private final Logger log = Exec.getLogger(GcsAuthentication.class);
27
- private final Optional<String> serviceAccountEmail;
28
- private final Optional<String> p12KeyFilePath;
29
- private final Optional<String> jsonKeyFilePath;
30
- private final String applicationName;
31
- private final HttpTransport httpTransport;
32
- private final JsonFactory jsonFactory;
33
- private final HttpRequestInitializer credentials;
34
-
35
- public GcsAuthentication(String authMethod, Optional<String> serviceAccountEmail,
36
- Optional<String> p12KeyFilePath, Optional<String> jsonKeyFilePath, String applicationName)
37
- throws IOException, GeneralSecurityException
38
- {
39
- this.serviceAccountEmail = serviceAccountEmail;
40
- this.p12KeyFilePath = p12KeyFilePath;
41
- this.jsonKeyFilePath = jsonKeyFilePath;
42
- this.applicationName = applicationName;
43
-
44
- this.httpTransport = new ApacheHttpTransport.Builder().build();
45
- this.jsonFactory = new JacksonFactory();
46
-
47
- if (authMethod.equals("compute_engine")) {
48
- this.credentials = getComputeCredential();
49
- } else if(authMethod.toLowerCase().equals("json_key")) {
50
- this.credentials = getServiceAccountCredentialFromJsonFile();
51
- } else {
52
- this.credentials = getServiceAccountCredential();
53
- }
54
- }
55
-
56
- /**
57
- * @see https://developers.google.com/accounts/docs/OAuth2ServiceAccount#authorizingrequests
58
- */
59
- private GoogleCredential getServiceAccountCredential() throws IOException, GeneralSecurityException
60
- {
61
- // @see https://cloud.google.com/compute/docs/api/how-tos/authorization
62
- // @see https://developers.google.com/resources/api-libraries/documentation/storage/v1/java/latest/com/google/api/services/storage/STORAGE_SCOPE.html
63
- // @see https://developers.google.com/resources/api-libraries/documentation/bigquery/v2/java/latest/com/google/api/services/bigquery/BigqueryScopes.html
64
- return new GoogleCredential.Builder()
65
- .setTransport(httpTransport)
66
- .setJsonFactory(jsonFactory)
67
- .setServiceAccountId(serviceAccountEmail.orNull())
68
- .setServiceAccountScopes(
69
- ImmutableList.of(
70
- StorageScopes.DEVSTORAGE_READ_WRITE
71
- )
72
- )
73
- .setServiceAccountPrivateKeyFromP12File(new File(p12KeyFilePath.orNull()))
74
- .build();
75
- }
76
-
77
- private GoogleCredential getServiceAccountCredentialFromJsonFile() throws IOException
78
- {
79
- FileInputStream stream = new FileInputStream(jsonKeyFilePath.orNull());
80
-
81
- return GoogleCredential.fromStream(stream, httpTransport, jsonFactory)
82
- .createScoped(Collections.singleton(StorageScopes.DEVSTORAGE_READ_WRITE));
83
- }
84
-
85
- /**
86
- * @see http://developers.guge.io/accounts/docs/OAuth2ServiceAccount#creatinganaccount
87
- * @see https://developers.google.com/accounts/docs/OAuth2
88
- */
89
- private ComputeCredential getComputeCredential() throws IOException
90
- {
91
- ComputeCredential credential = new ComputeCredential.Builder(httpTransport, jsonFactory)
92
- .build();
93
- credential.refreshToken();
94
-
95
- return credential;
96
- }
97
-
98
- public Storage getGcsClient(String bucket) throws GoogleJsonResponseException, IOException
99
- {
100
- Storage client = new Storage.Builder(httpTransport, jsonFactory, credentials)
101
- .setApplicationName(applicationName)
102
- .build();
103
-
104
- // For throw IOException when authentication is fail.
105
- long maxResults = 1;
106
- Objects objects = client.objects().list(bucket).setMaxResults(maxResults).execute();
107
-
108
- return client;
109
- }
110
- }
34
+ private final Logger log = Exec.getLogger(GcsAuthentication.class);
35
+ private final Optional<String> serviceAccountEmail;
36
+ private final Optional<String> p12KeyFilePath;
37
+ private final Optional<String> jsonKeyFilePath;
38
+ private final String applicationName;
39
+ private final HttpTransport httpTransport;
40
+ private final JsonFactory jsonFactory;
41
+ private final HttpRequestInitializer credentials;
42
+
43
+ public GcsAuthentication(String authMethod, Optional<String> serviceAccountEmail,
44
+ Optional<String> p12KeyFilePath, Optional<String> jsonKeyFilePath, String applicationName)
45
+ throws IOException, GeneralSecurityException
46
+ {
47
+ this.serviceAccountEmail = serviceAccountEmail;
48
+ this.p12KeyFilePath = p12KeyFilePath;
49
+ this.jsonKeyFilePath = jsonKeyFilePath;
50
+ this.applicationName = applicationName;
51
+
52
+ this.httpTransport = new ApacheHttpTransport.Builder().build();
53
+ this.jsonFactory = new JacksonFactory();
54
+
55
+ if (authMethod.equals("compute_engine")) {
56
+ this.credentials = getComputeCredential();
57
+ }
58
+ else if (authMethod.toLowerCase().equals("json_key")) {
59
+ this.credentials = getServiceAccountCredentialFromJsonFile();
60
+ }
61
+ else {
62
+ this.credentials = getServiceAccountCredential();
63
+ }
64
+ }
65
+
66
+ /**
67
+ * @see https://developers.google.com/accounts/docs/OAuth2ServiceAccount#authorizingrequests
68
+ */
69
+ private GoogleCredential getServiceAccountCredential() throws IOException, GeneralSecurityException
70
+ {
71
+ // @see https://cloud.google.com/compute/docs/api/how-tos/authorization
72
+ // @see https://developers.google.com/resources/api-libraries/documentation/storage/v1/java/latest/com/google/api/services/storage/STORAGE_SCOPE.html
73
+ // @see https://developers.google.com/resources/api-libraries/documentation/bigquery/v2/java/latest/com/google/api/services/bigquery/BigqueryScopes.html
74
+ return new GoogleCredential.Builder()
75
+ .setTransport(httpTransport)
76
+ .setJsonFactory(jsonFactory)
77
+ .setServiceAccountId(serviceAccountEmail.orNull())
78
+ .setServiceAccountScopes(
79
+ ImmutableList.of(
80
+ StorageScopes.DEVSTORAGE_READ_WRITE
81
+ )
82
+ )
83
+ .setServiceAccountPrivateKeyFromP12File(new File(p12KeyFilePath.get()))
84
+ .build();
85
+ }
86
+
87
+ private GoogleCredential getServiceAccountCredentialFromJsonFile() throws IOException
88
+ {
89
+ FileInputStream stream = new FileInputStream(jsonKeyFilePath.get());
90
+
91
+ return GoogleCredential.fromStream(stream, httpTransport, jsonFactory)
92
+ .createScoped(Collections.singleton(StorageScopes.DEVSTORAGE_READ_WRITE));
93
+ }
94
+
95
+ /**
96
+ * @see http://developers.guge.io/accounts/docs/OAuth2ServiceAccount#creatinganaccount
97
+ * @see https://developers.google.com/accounts/docs/OAuth2
98
+ */
99
+ private ComputeCredential getComputeCredential() throws IOException
100
+ {
101
+ ComputeCredential credential = new ComputeCredential.Builder(httpTransport, jsonFactory)
102
+ .build();
103
+ credential.refreshToken();
104
+
105
+ return credential;
106
+ }
107
+
108
+ public Storage getGcsClient(final String bucket, int maxConnectionRetry) throws ConfigException, IOException
109
+ {
110
+ try {
111
+ return retryExecutor()
112
+ .withRetryLimit(maxConnectionRetry)
113
+ .withInitialRetryWait(500)
114
+ .withMaxRetryWait(30 * 1000)
115
+ .runInterruptible(new Retryable<Storage>() {
116
+ @Override
117
+ public Storage call() throws IOException, RetryGiveupException
118
+ {
119
+ Storage client = new Storage.Builder(httpTransport, jsonFactory, credentials)
120
+ .setApplicationName(applicationName)
121
+ .build();
122
+
123
+ // For throw ConfigException when authentication is fail.
124
+ long maxResults = 1;
125
+ client.objects().list(bucket).setMaxResults(maxResults).execute();
126
+
127
+ return client;
128
+ }
129
+
130
+ @Override
131
+ public boolean isRetryableException(Exception exception)
132
+ {
133
+ if (exception instanceof GoogleJsonResponseException || exception instanceof TokenResponseException) {
134
+ int statusCode;
135
+ if (exception instanceof GoogleJsonResponseException) {
136
+ if (((GoogleJsonResponseException) exception).getDetails() == null) {
137
+ String content = "";
138
+ if (((GoogleJsonResponseException) exception).getContent() != null) {
139
+ content = ((GoogleJsonResponseException) exception).getContent();
140
+ }
141
+ log.warn("Invalid response was returned : {}", content);
142
+ return true;
143
+ }
144
+ statusCode = ((GoogleJsonResponseException) exception).getDetails().getCode();
145
+ }
146
+ else {
147
+ statusCode = ((TokenResponseException) exception).getStatusCode();
148
+ }
149
+ if (statusCode / 100 == 4) {
150
+ return false;
151
+ }
152
+ }
153
+ return true;
154
+ }
155
+
156
+ @Override
157
+ public void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait)
158
+ throws RetryGiveupException
159
+ {
160
+ String message = String.format("GCS GET request failed. Retrying %d/%d after %d seconds. Message: %s: %s",
161
+ retryCount, retryLimit, retryWait / 1000, exception.getClass(), exception.getMessage());
162
+ if (retryCount % 3 == 0) {
163
+ log.warn(message, exception);
164
+ }
165
+ else {
166
+ log.warn(message);
167
+ }
168
+ }
169
+
170
+ @Override
171
+ public void onGiveup(Exception firstException, Exception lastException)
172
+ throws RetryGiveupException
173
+ {
174
+ }
175
+ });
176
+ }
177
+ catch (RetryGiveupException ex) {
178
+ if (ex.getCause() instanceof GoogleJsonResponseException || ex.getCause() instanceof TokenResponseException) {
179
+ int statusCode = 0;
180
+ if (ex.getCause() instanceof GoogleJsonResponseException) {
181
+ if (((GoogleJsonResponseException) ex.getCause()).getDetails() != null) {
182
+ statusCode = ((GoogleJsonResponseException) ex.getCause()).getDetails().getCode();
183
+ }
184
+ }
185
+ else if (ex.getCause() instanceof TokenResponseException) {
186
+ statusCode = ((TokenResponseException) ex.getCause()).getStatusCode();
187
+ }
188
+ if (statusCode / 100 == 4) {
189
+ throw new ConfigException(ex);
190
+ }
191
+ }
192
+ throw Throwables.propagate(ex);
193
+ }
194
+ catch (InterruptedException ex) {
195
+ throw new InterruptedIOException();
196
+ }
197
+ }
198
+ }