embulk-input-gcs 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/secretkeys.tar DELETED
Binary file
data/secretkeys.tar.enc DELETED
Binary file
@@ -1,206 +0,0 @@
1
- package org.embulk.input.gcs;
2
-
3
- import com.google.api.client.auth.oauth2.TokenResponseException;
4
- import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
5
- import com.google.api.client.googleapis.compute.ComputeCredential;
6
- import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
7
- import com.google.api.client.googleapis.json.GoogleJsonResponseException;
8
- import com.google.api.client.http.HttpRequestInitializer;
9
- import com.google.api.client.http.HttpTransport;
10
- import com.google.api.client.json.JsonFactory;
11
- import com.google.api.client.json.jackson2.JacksonFactory;
12
- import com.google.api.services.storage.Storage;
13
- import com.google.api.services.storage.StorageScopes;
14
- import com.google.common.base.Throwables;
15
- import com.google.common.collect.ImmutableList;
16
- import org.embulk.config.ConfigException;
17
- import org.embulk.spi.Exec;
18
- import org.embulk.spi.util.RetryExecutor.RetryGiveupException;
19
- import org.embulk.spi.util.RetryExecutor.Retryable;
20
- import org.slf4j.Logger;
21
- import static org.embulk.spi.util.RetryExecutor.retryExecutor;
22
-
23
- import java.io.File;
24
- import java.io.FileInputStream;
25
-
26
- import java.io.IOException;
27
- import java.io.InterruptedIOException;
28
- import java.security.GeneralSecurityException;
29
- import java.util.Collections;
30
- import java.util.Optional;
31
-
32
- public class GcsAuthentication
33
- {
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 = GoogleNetHttpTransport.newTrustedTransport();
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.orElseGet(null))
78
- .setServiceAccountScopes(
79
- ImmutableList.of(
80
- StorageScopes.DEVSTORAGE_READ_ONLY
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_ONLY));
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) {
134
- if (((GoogleJsonResponseException) exception).getDetails() == null) {
135
- if (((GoogleJsonResponseException) exception).getContent() != null) {
136
- String content = ((GoogleJsonResponseException) exception).getContent();
137
- log.warn("Invalid response was returned : {}", content);
138
- return true;
139
- }
140
- }
141
- int statusCode = ((GoogleJsonResponseException) exception).getDetails().getCode();
142
- return !(statusCode / 100 == 4);
143
- }
144
- else if (exception instanceof TokenResponseException) {
145
- TokenResponseException ex = (TokenResponseException) exception;
146
- if (ex.getDetails() != null && ex.getDetails().getErrorDescription() != null) {
147
- String errorDescription = ex.getDetails().getErrorDescription();
148
- // Retry: 400 BadRequest "Invalid JWT..."
149
- // Caused by: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
150
- // {
151
- // "error" : "invalid_grant",
152
- // "error_description" : "Invalid JWT: No valid verifier found for issuer."
153
- // }
154
- if (errorDescription.contains("Invalid JWT")) {
155
- log.warn("Invalid response was returned : {}", errorDescription);
156
- return true;
157
- }
158
- }
159
- return !(ex.getStatusCode() / 100 == 4);
160
- }
161
- return true;
162
- }
163
-
164
- @Override
165
- public void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait)
166
- throws RetryGiveupException
167
- {
168
- String message = String.format("GCS GET request failed. Retrying %d/%d after %d seconds. Message: %s: %s",
169
- retryCount, retryLimit, retryWait / 1000, exception.getClass(), exception.getMessage());
170
- if (retryCount % 3 == 0) {
171
- log.warn(message, exception);
172
- }
173
- else {
174
- log.warn(message);
175
- }
176
- }
177
-
178
- @Override
179
- public void onGiveup(Exception firstException, Exception lastException)
180
- throws RetryGiveupException
181
- {
182
- }
183
- });
184
- }
185
- catch (RetryGiveupException ex) {
186
- if (ex.getCause() instanceof GoogleJsonResponseException || ex.getCause() instanceof TokenResponseException) {
187
- int statusCode = 0;
188
- if (ex.getCause() instanceof GoogleJsonResponseException) {
189
- if (((GoogleJsonResponseException) ex.getCause()).getDetails() != null) {
190
- statusCode = ((GoogleJsonResponseException) ex.getCause()).getDetails().getCode();
191
- }
192
- }
193
- else if (ex.getCause() instanceof TokenResponseException) {
194
- statusCode = ((TokenResponseException) ex.getCause()).getStatusCode();
195
- }
196
- if (statusCode / 100 == 4) {
197
- throw new ConfigException(ex);
198
- }
199
- }
200
- throw Throwables.propagate(ex);
201
- }
202
- catch (InterruptedException ex) {
203
- throw new InterruptedIOException();
204
- }
205
- }
206
- }
@@ -1,185 +0,0 @@
1
- package org.embulk.input.gcs;
2
-
3
- import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
4
- import com.google.api.services.storage.Storage;
5
- import org.embulk.EmbulkTestRuntime;
6
- import org.embulk.config.ConfigException;
7
- import org.junit.BeforeClass;
8
- import org.junit.Rule;
9
- import org.junit.Test;
10
-
11
- import java.io.FileNotFoundException;
12
-
13
- import java.io.IOException;
14
- import java.lang.reflect.Field;
15
- import java.security.GeneralSecurityException;
16
- import java.util.Optional;
17
-
18
- import static org.junit.Assert.assertEquals;
19
- import static org.junit.Assume.assumeNotNull;
20
-
21
- public class TestGcsAuthentication
22
- {
23
- private static Optional<String> GCP_EMAIL;
24
- private static Optional<String> GCP_P12_KEYFILE;
25
- private static Optional<String> GCP_JSON_KEYFILE;
26
- private static String GCP_BUCKET;
27
- private static final String GCP_APPLICATION_NAME = "embulk-input-gcs";
28
- private static int MAX_CONNECTION_RETRY = 3;
29
-
30
- /*
31
- * This test case requires environment variables
32
- * GCP_EMAIL
33
- * GCP_P12_KEYFILE
34
- * GCP_JSON_KEYFILE
35
- * GCP_BUCKET
36
- */
37
- @BeforeClass
38
- public static void initializeConstant()
39
- {
40
- String gcpEmail = System.getenv("GCP_EMAIL");
41
- String gcpP12KeyFile = System.getenv("GCP_P12_KEYFILE");
42
- String gcpJsonKeyFile = System.getenv("GCP_JSON_KEYFILE");
43
- String gcpBucket = System.getenv("GCP_BUCKET");
44
-
45
- // skip test cases, if environment variables are not set.
46
- assumeNotNull(gcpEmail, gcpP12KeyFile, gcpJsonKeyFile, gcpBucket);
47
-
48
- GCP_EMAIL = Optional.of(gcpEmail);
49
- GCP_P12_KEYFILE = Optional.of(gcpP12KeyFile);
50
- GCP_JSON_KEYFILE = Optional.of(gcpJsonKeyFile);
51
- GCP_BUCKET = gcpBucket;
52
- }
53
-
54
- @Rule
55
- public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
56
-
57
- @Test
58
- public void testGetServiceAccountCredentialSuccess()
59
- throws NoSuchFieldException, IllegalAccessException, GeneralSecurityException, IOException
60
- {
61
- GcsAuthentication auth = new GcsAuthentication(
62
- "private_key",
63
- GCP_EMAIL,
64
- GCP_P12_KEYFILE,
65
- null,
66
- GCP_APPLICATION_NAME
67
- );
68
-
69
- Field field = GcsAuthentication.class.getDeclaredField("credentials");
70
- field.setAccessible(true);
71
-
72
- assertEquals(GoogleCredential.class, field.get(auth).getClass());
73
- }
74
-
75
- @Test(expected = FileNotFoundException.class)
76
- public void testGetServiceAccountCredentialThrowFileNotFoundException()
77
- throws GeneralSecurityException, IOException
78
- {
79
- Optional<String> notFoundP12Keyfile = Optional.of("/path/to/notfound.p12");
80
- GcsAuthentication auth = new GcsAuthentication(
81
- "private_key",
82
- GCP_EMAIL,
83
- notFoundP12Keyfile,
84
- null,
85
- GCP_APPLICATION_NAME
86
- );
87
- }
88
-
89
- @Test
90
- public void testGetGcsClientUsingServiceAccountCredentialSuccess()
91
- throws NoSuchFieldException, IllegalAccessException, GeneralSecurityException, IOException
92
- {
93
- GcsAuthentication auth = new GcsAuthentication(
94
- "private_key",
95
- GCP_EMAIL,
96
- GCP_P12_KEYFILE,
97
- null,
98
- GCP_APPLICATION_NAME
99
- );
100
-
101
- Storage client = auth.getGcsClient(GCP_BUCKET, MAX_CONNECTION_RETRY);
102
-
103
- assertEquals(Storage.class, client.getClass());
104
- }
105
-
106
- @Test(expected = ConfigException.class)
107
- public void testGetGcsClientUsingServiceAccountCredentialThrowJsonResponseException()
108
- throws NoSuchFieldException, IllegalAccessException, GeneralSecurityException, IOException
109
- {
110
- GcsAuthentication auth = new GcsAuthentication(
111
- "private_key",
112
- GCP_EMAIL,
113
- GCP_P12_KEYFILE,
114
- null,
115
- GCP_APPLICATION_NAME
116
- );
117
-
118
- Storage client = auth.getGcsClient("non-exists-bucket", MAX_CONNECTION_RETRY);
119
-
120
- assertEquals(Storage.class, client.getClass());
121
- }
122
-
123
- @Test
124
- public void testGetServiceAccountCredentialFromJsonFileSuccess()
125
- throws NoSuchFieldException, IllegalAccessException, GeneralSecurityException, IOException
126
- {
127
- GcsAuthentication auth = new GcsAuthentication(
128
- "json_key",
129
- GCP_EMAIL,
130
- null,
131
- GCP_JSON_KEYFILE,
132
- GCP_APPLICATION_NAME
133
- );
134
- Field field = GcsAuthentication.class.getDeclaredField("credentials");
135
- field.setAccessible(true);
136
-
137
- assertEquals(GoogleCredential.class, field.get(auth).getClass());
138
- }
139
-
140
- @Test(expected = FileNotFoundException.class)
141
- public void testGetServiceAccountCredentialFromJsonThrowFileFileNotFoundException()
142
- throws GeneralSecurityException, IOException
143
- {
144
- Optional<String> notFoundJsonKeyfile = Optional.of("/path/to/notfound.json");
145
- GcsAuthentication auth = new GcsAuthentication(
146
- "json_key",
147
- GCP_EMAIL,
148
- null,
149
- notFoundJsonKeyfile,
150
- GCP_APPLICATION_NAME
151
- );
152
- }
153
-
154
- @Test
155
- public void testGetServiceAccountCredentialFromJsonSuccess()
156
- throws NoSuchFieldException, IllegalAccessException, GeneralSecurityException, IOException
157
- {
158
- GcsAuthentication auth = new GcsAuthentication(
159
- "json_key",
160
- GCP_EMAIL,
161
- null,
162
- GCP_JSON_KEYFILE,
163
- GCP_APPLICATION_NAME
164
- );
165
-
166
- Storage client = auth.getGcsClient(GCP_BUCKET, MAX_CONNECTION_RETRY);
167
-
168
- assertEquals(Storage.class, client.getClass());
169
- }
170
-
171
- @Test(expected = ConfigException.class)
172
- public void testGetServiceAccountCredentialFromJsonThrowGoogleJsonResponseException()
173
- throws NoSuchFieldException, IllegalAccessException, GeneralSecurityException, IOException
174
- {
175
- GcsAuthentication auth = new GcsAuthentication(
176
- "json_key",
177
- GCP_EMAIL,
178
- null,
179
- GCP_JSON_KEYFILE,
180
- GCP_APPLICATION_NAME
181
- );
182
-
183
- Storage client = auth.getGcsClient("non-exists-bucket", MAX_CONNECTION_RETRY);
184
- }
185
- }
Binary file