embulk-output-gcs 0.1.1 → 0.2.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 +4 -4
- data/README.md +25 -0
- data/build.gradle +3 -3
- data/classpath/embulk-output-gcs-0.2.0.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.properties +2 -2
- data/src/main/java/org/embulk/output/GcsAuthentication.java +96 -0
- data/src/main/java/org/embulk/output/GcsOutputPlugin.java +44 -47
- metadata +4 -3
- data/classpath/embulk-output-gcs-0.1.1.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94fccd956be721058fbf74ffd57017d05caf8e5b
|
4
|
+
data.tar.gz: e7e35ef7704225a633d47babdd21c91edd6ad272
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b2325cf0230d16f57fb7a247a9237428fd2d4527cd6848367a5989e3d8bc9a9da7f282b3a81ec97ad2425da9bb70cbd0a26465fcc1dd747ce3e804908cd48ad
|
7
|
+
data.tar.gz: ceb4828ba593c2e2ab8cf043bce26b4509867489cf3b7eac96fd00f1ef10b5ffe8895587a1844d7b01671ea0373cd30b82d39a94da2caf8183cdee206dcdd4e7
|
data/README.md
CHANGED
@@ -15,6 +15,7 @@ Google Cloud Storage output plugin for [Embulk](https://github.com/embulk/embulk
|
|
15
15
|
- **path_prefix**: Prefix of output keys (string, required)
|
16
16
|
- **file_ext**: Extention of output file (string, required)
|
17
17
|
- **content_type**: content type of output file (string, optional, default value is "application/octet-stream")
|
18
|
+
- **auth_method**: Authentication method `private_key` or `compute_engine` (string, optional, default value is "private_key")
|
18
19
|
- **service_account_email**: Google Cloud Platform service account email (string, required)
|
19
20
|
- **p12_keyfile_path**: Private key file fullpath of Google Cloud Platform service account (string, required)
|
20
21
|
- **application_name**: Application name, anything you like (string, optional, default value is "embulk-output-gcs")
|
@@ -27,6 +28,7 @@ out:
|
|
27
28
|
bucket: your-gcs-bucket-name
|
28
29
|
path_prefix: logs/out
|
29
30
|
file_ext: .csv
|
31
|
+
auth_method: `private_key` #default
|
30
32
|
service_account_email: 'XYZ@developer.gserviceaccount.com'
|
31
33
|
p12_keyfile_path: '/path/to/private/key.p12'
|
32
34
|
formatter:
|
@@ -34,6 +36,29 @@ out:
|
|
34
36
|
encoding: UTF-8
|
35
37
|
```
|
36
38
|
|
39
|
+
## Authentication
|
40
|
+
|
41
|
+
There are two methods supported to fetch access token for the service account.
|
42
|
+
|
43
|
+
1. Public-Private key pair
|
44
|
+
2. Pre-defined access token (Compute Engine only)
|
45
|
+
|
46
|
+
The examples above use the first one. You first need to create a service account (client ID),
|
47
|
+
download its private key and deploy the key with embulk.
|
48
|
+
|
49
|
+
On the other hand, you don't need to explicitly create a service account for embulk when you
|
50
|
+
run embulk in Google Compute Engine. In this second authentication method, you need to
|
51
|
+
add the API scope "https://www.googleapis.com/auth/devstorage.read_write" to the scope list of your
|
52
|
+
Compute Engine instance, then you can configure embulk like this.
|
53
|
+
|
54
|
+
[Setting the scope of service account access for instances](https://cloud.google.com/compute/docs/authentication)
|
55
|
+
|
56
|
+
```yaml
|
57
|
+
out:
|
58
|
+
type: gcs
|
59
|
+
auth_method: compute_engine
|
60
|
+
```
|
61
|
+
|
37
62
|
## Build
|
38
63
|
|
39
64
|
```
|
data/build.gradle
CHANGED
@@ -15,11 +15,11 @@ configurations {
|
|
15
15
|
sourceCompatibility = 1.7
|
16
16
|
targetCompatibility = 1.7
|
17
17
|
|
18
|
-
version = "0.
|
18
|
+
version = "0.2.0"
|
19
19
|
|
20
20
|
dependencies {
|
21
|
-
compile "org.embulk:embulk-core:0.
|
22
|
-
provided "org.embulk:embulk-core:0.
|
21
|
+
compile "org.embulk:embulk-core:0.7.3"
|
22
|
+
provided "org.embulk:embulk-core:0.7.3"
|
23
23
|
|
24
24
|
compile "com.google.http-client:google-http-client-jackson2:1.19.0"
|
25
25
|
compile ("com.google.apis:google-api-services-storage:v1-rev28-1.19.1") {exclude module: "guava-jdk5"}
|
Binary file
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
#Tue Aug 11 00:26:20 PDT 2015
|
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
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip
|
@@ -0,0 +1,96 @@
|
|
1
|
+
package org.embulk.output;
|
2
|
+
|
3
|
+
import java.io.File;
|
4
|
+
import java.io.IOException;
|
5
|
+
|
6
|
+
import com.google.api.client.http.apache.ApacheHttpTransport;
|
7
|
+
import com.google.api.services.storage.model.Objects;
|
8
|
+
import com.google.common.base.Optional;
|
9
|
+
import com.google.common.collect.ImmutableList;
|
10
|
+
import java.security.GeneralSecurityException;
|
11
|
+
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
12
|
+
import com.google.api.client.googleapis.compute.ComputeCredential;
|
13
|
+
import com.google.api.client.http.HttpTransport;
|
14
|
+
import com.google.api.client.json.JsonFactory;
|
15
|
+
import com.google.api.client.json.jackson2.JacksonFactory;
|
16
|
+
import com.google.api.client.http.HttpRequestInitializer;
|
17
|
+
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
18
|
+
import com.google.api.services.storage.Storage;
|
19
|
+
import com.google.api.services.storage.StorageScopes;
|
20
|
+
import org.embulk.spi.Exec;
|
21
|
+
import org.slf4j.Logger;
|
22
|
+
|
23
|
+
public class GcsAuthentication
|
24
|
+
{
|
25
|
+
private final Logger log = Exec.getLogger(GcsAuthentication.class);
|
26
|
+
private final Optional<String> serviceAccountEmail;
|
27
|
+
private final Optional<String> p12KeyFilePath;
|
28
|
+
private final String applicationName;
|
29
|
+
private final HttpTransport httpTransport;
|
30
|
+
private final JsonFactory jsonFactory;
|
31
|
+
private final HttpRequestInitializer credentials;
|
32
|
+
|
33
|
+
public GcsAuthentication(String authMethod, Optional<String> serviceAccountEmail, Optional<String> p12KeyFilePath, String applicationName)
|
34
|
+
throws IOException, GeneralSecurityException
|
35
|
+
{
|
36
|
+
this.serviceAccountEmail = serviceAccountEmail;
|
37
|
+
this.p12KeyFilePath = p12KeyFilePath;
|
38
|
+
this.applicationName = applicationName;
|
39
|
+
|
40
|
+
this.httpTransport = new ApacheHttpTransport.Builder().build();
|
41
|
+
this.jsonFactory = new JacksonFactory();
|
42
|
+
|
43
|
+
if (authMethod.equals("compute_engine")) {
|
44
|
+
this.credentials = getComputeCredential();
|
45
|
+
} else {
|
46
|
+
this.credentials = getServiceAccountCredential();
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* @see https://developers.google.com/accounts/docs/OAuth2ServiceAccount#authorizingrequests
|
52
|
+
*/
|
53
|
+
private GoogleCredential getServiceAccountCredential() throws IOException, GeneralSecurityException
|
54
|
+
{
|
55
|
+
// @see https://cloud.google.com/compute/docs/api/how-tos/authorization
|
56
|
+
// @see https://developers.google.com/resources/api-libraries/documentation/storage/v1/java/latest/com/google/api/services/storage/STORAGE_SCOPE.html
|
57
|
+
// @see https://developers.google.com/resources/api-libraries/documentation/bigquery/v2/java/latest/com/google/api/services/bigquery/BigqueryScopes.html
|
58
|
+
return new GoogleCredential.Builder()
|
59
|
+
.setTransport(httpTransport)
|
60
|
+
.setJsonFactory(jsonFactory)
|
61
|
+
.setServiceAccountId(serviceAccountEmail.orNull())
|
62
|
+
.setServiceAccountScopes(
|
63
|
+
ImmutableList.of(
|
64
|
+
StorageScopes.DEVSTORAGE_READ_WRITE
|
65
|
+
)
|
66
|
+
)
|
67
|
+
.setServiceAccountPrivateKeyFromP12File(new File(p12KeyFilePath.orNull()))
|
68
|
+
.build();
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* @see http://developers.guge.io/accounts/docs/OAuth2ServiceAccount#creatinganaccount
|
73
|
+
* @see https://developers.google.com/accounts/docs/OAuth2
|
74
|
+
*/
|
75
|
+
private ComputeCredential getComputeCredential() throws IOException
|
76
|
+
{
|
77
|
+
ComputeCredential credential = new ComputeCredential.Builder(httpTransport, jsonFactory)
|
78
|
+
.build();
|
79
|
+
credential.refreshToken();
|
80
|
+
|
81
|
+
return credential;
|
82
|
+
}
|
83
|
+
|
84
|
+
public Storage getGcsClient(String bucket) throws GoogleJsonResponseException, IOException
|
85
|
+
{
|
86
|
+
Storage client = new Storage.Builder(httpTransport, jsonFactory, credentials)
|
87
|
+
.setApplicationName(applicationName)
|
88
|
+
.build();
|
89
|
+
|
90
|
+
// For throw IOException when authentication is fail.
|
91
|
+
long maxResults = 1;
|
92
|
+
Objects objects = client.objects().list(bucket).setMaxResults(maxResults).execute();
|
93
|
+
|
94
|
+
return client;
|
95
|
+
}
|
96
|
+
}
|
@@ -1,22 +1,16 @@
|
|
1
1
|
package org.embulk.output;
|
2
2
|
|
3
|
-
import com.google.api.client.auth.oauth2.Credential;
|
4
|
-
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
5
|
-
import com.google.api.client.http.HttpTransport;
|
6
3
|
import com.google.api.client.http.InputStreamContent;
|
7
|
-
import com.google.api.client.http.apache.ApacheHttpTransport;
|
8
|
-
import com.google.api.client.json.JsonFactory;
|
9
|
-
import com.google.api.client.json.jackson2.JacksonFactory;
|
10
4
|
import com.google.api.services.storage.Storage;
|
11
|
-
import com.google.api.services.storage.StorageScopes;
|
12
5
|
import com.google.api.services.storage.model.StorageObject;
|
6
|
+
import com.google.common.base.Optional;
|
13
7
|
import com.google.common.base.Throwables;
|
14
|
-
import
|
15
|
-
import org.embulk.config.CommitReport;
|
8
|
+
import org.embulk.config.TaskReport;
|
16
9
|
import org.embulk.config.Config;
|
17
10
|
import org.embulk.config.ConfigDefault;
|
18
11
|
import org.embulk.config.ConfigDiff;
|
19
12
|
import org.embulk.config.ConfigSource;
|
13
|
+
import org.embulk.config.ConfigException;
|
20
14
|
import org.embulk.config.Task;
|
21
15
|
import org.embulk.config.TaskSource;
|
22
16
|
import org.embulk.spi.Buffer;
|
@@ -25,7 +19,6 @@ import org.embulk.spi.FileOutputPlugin;
|
|
25
19
|
import org.embulk.spi.TransactionalFileOutput;
|
26
20
|
import org.slf4j.Logger;
|
27
21
|
|
28
|
-
import java.io.File;
|
29
22
|
import java.io.IOException;
|
30
23
|
import java.io.PipedInputStream;
|
31
24
|
import java.io.PipedOutputStream;
|
@@ -40,35 +33,40 @@ import java.util.concurrent.Future;
|
|
40
33
|
|
41
34
|
public class GcsOutputPlugin implements FileOutputPlugin {
|
42
35
|
private static final Logger logger = Exec.getLogger(GcsOutputPlugin.class);
|
43
|
-
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
|
44
36
|
|
45
37
|
public interface PluginTask extends Task {
|
46
38
|
@Config("bucket")
|
47
|
-
|
39
|
+
String getBucket();
|
48
40
|
|
49
41
|
@Config("path_prefix")
|
50
|
-
|
42
|
+
String getPathPrefix();
|
51
43
|
|
52
44
|
@Config("file_ext")
|
53
|
-
|
45
|
+
String getFileNameExtension();
|
54
46
|
|
55
47
|
@Config("sequence_format")
|
56
48
|
@ConfigDefault("\".%03d.%02d\"")
|
57
|
-
|
49
|
+
String getSequenceFormat();
|
58
50
|
|
59
51
|
@Config("content_type")
|
60
52
|
@ConfigDefault("\"application/octet-stream\"")
|
61
|
-
|
53
|
+
String getContentType();
|
54
|
+
|
55
|
+
@Config("auth_method")
|
56
|
+
@ConfigDefault("\"private_key\"")
|
57
|
+
AuthMethod getAuthMethod();
|
62
58
|
|
63
59
|
@Config("service_account_email")
|
64
|
-
|
60
|
+
@ConfigDefault("null")
|
61
|
+
Optional<String> getServiceAccountEmail();
|
65
62
|
|
66
63
|
@Config("p12_keyfile_path")
|
67
|
-
|
64
|
+
@ConfigDefault("null")
|
65
|
+
Optional<String> getP12KeyfilePath();
|
68
66
|
|
69
67
|
@Config("application_name")
|
70
68
|
@ConfigDefault("\"embulk-output-gcs\"")
|
71
|
-
|
69
|
+
String getApplicationName();
|
72
70
|
}
|
73
71
|
|
74
72
|
@Override
|
@@ -90,7 +88,7 @@ public class GcsOutputPlugin implements FileOutputPlugin {
|
|
90
88
|
@Override
|
91
89
|
public void cleanup(TaskSource taskSource,
|
92
90
|
int taskCount,
|
93
|
-
List<
|
91
|
+
List<TaskReport> successTaskReports) {
|
94
92
|
}
|
95
93
|
|
96
94
|
@Override
|
@@ -101,34 +99,15 @@ public class GcsOutputPlugin implements FileOutputPlugin {
|
|
101
99
|
return new TransactionalGcsFileOutput(task, client, taskIndex);
|
102
100
|
}
|
103
101
|
|
104
|
-
private
|
102
|
+
private Storage createClient(final PluginTask task) {
|
103
|
+
Storage client = null;
|
105
104
|
try {
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
.setTransport(httpTransport)
|
111
|
-
.setJsonFactory(JSON_FACTORY)
|
112
|
-
.setServiceAccountId(task.getServiceAccountEmail())
|
113
|
-
.setServiceAccountScopes(ImmutableList.of(StorageScopes.DEVSTORAGE_READ_WRITE))
|
114
|
-
.setServiceAccountPrivateKeyFromP12File(new File(task.getP12KeyfilePath()))
|
115
|
-
.build();
|
116
|
-
return cred;
|
117
|
-
} catch (IOException ex) {
|
118
|
-
logger.error(String.format("Could not load client secrets file %s", task.getP12KeyfilePath()));
|
119
|
-
throw Throwables.propagate(ex);
|
120
|
-
} catch (GeneralSecurityException ex) {
|
121
|
-
logger.error("Google Authentication was failed");
|
122
|
-
throw Throwables.propagate(ex);
|
105
|
+
GcsAuthentication auth = new GcsAuthentication(task.getAuthMethod().getString(), task.getServiceAccountEmail(), task.getP12KeyfilePath(), task.getApplicationName());
|
106
|
+
client = auth.getGcsClient(task.getBucket());
|
107
|
+
} catch (GeneralSecurityException | IOException ex) {
|
108
|
+
throw new ConfigException(ex);
|
123
109
|
}
|
124
|
-
}
|
125
110
|
|
126
|
-
private Storage createClient(final PluginTask task) {
|
127
|
-
HttpTransport httpTransport = new ApacheHttpTransport.Builder().build();
|
128
|
-
Credential credential = createCredential(task, httpTransport);
|
129
|
-
Storage client = new Storage.Builder(httpTransport, JSON_FACTORY, credential)
|
130
|
-
.setApplicationName(task.getApplicationName())
|
131
|
-
.build();
|
132
111
|
return client;
|
133
112
|
}
|
134
113
|
|
@@ -194,8 +173,8 @@ public class GcsOutputPlugin implements FileOutputPlugin {
|
|
194
173
|
}
|
195
174
|
|
196
175
|
@Override
|
197
|
-
public
|
198
|
-
|
176
|
+
public TaskReport commit() {
|
177
|
+
TaskReport report = Exec.newTaskReport();
|
199
178
|
report.set("files", storageObjects);
|
200
179
|
return report;
|
201
180
|
}
|
@@ -250,4 +229,22 @@ public class GcsOutputPlugin implements FileOutputPlugin {
|
|
250
229
|
}
|
251
230
|
}
|
252
231
|
}
|
232
|
+
|
233
|
+
public enum AuthMethod
|
234
|
+
{
|
235
|
+
private_key("private_key"),
|
236
|
+
compute_engine("compute_engine");
|
237
|
+
|
238
|
+
private final String string;
|
239
|
+
|
240
|
+
AuthMethod(String string)
|
241
|
+
{
|
242
|
+
this.string = string;
|
243
|
+
}
|
244
|
+
|
245
|
+
public String getString()
|
246
|
+
{
|
247
|
+
return string;
|
248
|
+
}
|
249
|
+
}
|
253
250
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-output-gcs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kazuyuki Honda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,11 +59,12 @@ files:
|
|
59
59
|
- gradlew
|
60
60
|
- gradlew.bat
|
61
61
|
- lib/embulk/output/gcs.rb
|
62
|
+
- src/main/java/org/embulk/output/GcsAuthentication.java
|
62
63
|
- src/main/java/org/embulk/output/GcsOutputPlugin.java
|
63
64
|
- src/test/java/org/embulk/output/TestGcsOutputPlugin.java
|
64
65
|
- classpath/commons-codec-1.3.jar
|
65
66
|
- classpath/commons-logging-1.1.1.jar
|
66
|
-
- classpath/embulk-output-gcs-0.
|
67
|
+
- classpath/embulk-output-gcs-0.2.0.jar
|
67
68
|
- classpath/google-api-client-1.19.1.jar
|
68
69
|
- classpath/google-api-services-storage-v1-rev28-1.19.1.jar
|
69
70
|
- classpath/google-http-client-1.19.0.jar
|
Binary file
|