embulk-output-td 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fe85fa7501f82e0d7660c88ef9369629fe91827
4
- data.tar.gz: 9858b8eea57c1574c346d919dd9a57ba7ea44058
3
+ metadata.gz: a2b9d332f7623b5bcb26571bed0f2a021303d342
4
+ data.tar.gz: 5dde90bc97bbd9e19e76b553c81a750f8a4bf753
5
5
  SHA512:
6
- metadata.gz: 602fa7e84ed8e32444a6de50ceeb8333ba071e7ba546dbb46424a8e7c20ebdc21cd67705031e29fe602db1f5bd9a50b6bc08f682507aedef986b2d6741e6a20e
7
- data.tar.gz: 1960a94319e23a719273853bdffcd3151caa3cfe053bcdab45c5f70fe419a0650dcc07cb77a9ff495e9bea8aff7f3bd40e7c538fe3d9260eadffa08f387b2c2c
6
+ metadata.gz: c8500157a6ca8483718d72148064fab8b8b571d103e270bfd187175607b2dbac0af7196998329bc33c0813e584902158446cb5fad66475c41904ad7a652097c1
7
+ data.tar.gz: 4a564bbaec11724badc1a48a432578881c4489e44f495fbd68a3a93a957e71b79d3bc0b6870d8345e3ae5db41efc94c52be37e0adda525313d3773caf4685ef5
@@ -1,3 +1,6 @@
1
+ ## 0.5.3 - 2019-11-19
2
+ * [new feature] Added additional headers to the Http requests [#94](https://github.com/treasure-data/embulk-output-td/pul/94) addressed by [#93](https://github.com/treasure-data/embulk-output-td/issues/93)
3
+ * Also exposes `port` configuration (by default will use 80 and 443).
1
4
 
2
5
  ## 0.5.2 - 2019-10-24
3
6
  * [maintenance] Fix columns order bug described in issue [91](https://github.com/treasure-data/embulk-output-td/issues/91) [#92](https://github.com/treasure-data/embulk-output-td/pull/92)
data/README.md CHANGED
@@ -40,6 +40,8 @@
40
40
  - **retry_limit**: indicates how many retries are allowed (int, default: 20)
41
41
  - **retry_initial_interval_millis**: the initial intervals (int, default: 1000)
42
42
  - **retry_max_interval_millis**: the maximum intervals. The interval doubles every retry until retry_max_interval_millis is reached. (int, default: 90000)
43
+ - **additional_http_headers**: add additional headers to the requests (a key & value map, default: null)
44
+ - **port**: set port for Http requests. By default will connect to port 443 or 80 if `use_ssl: false` (int, optional)
43
45
 
44
46
  ## Modes
45
47
  * **append**:
@@ -88,6 +90,22 @@ out:
88
90
  mode: append
89
91
  ```
90
92
 
93
+ ### Additional Http headers
94
+ ```yaml
95
+ out:
96
+ type: td
97
+ apikey: <your apikey>
98
+ endpoint: api.treasuredata.com
99
+ database: my_db
100
+ table: my_table
101
+ time_column: created_at
102
+ auto_create_table: true
103
+ mode: append
104
+ additional_http_headers:
105
+ Content_Type: 'application/json'
106
+ foo: bar
107
+ ```
108
+
91
109
 
92
110
 
93
111
  ## Build
@@ -19,7 +19,7 @@ configurations {
19
19
  }
20
20
 
21
21
  group = "org.embulk.output.td"
22
- version = "0.5.2"
22
+ version = "0.5.3"
23
23
 
24
24
  compileJava.options.encoding = 'UTF-8' // source encoding
25
25
  sourceCompatibility = 1.8
@@ -38,6 +38,7 @@ dependencies {
38
38
  testCompile "org.bigtesting:fixd:1.0.0"
39
39
  testCompile "org.embulk:embulk-core:0.8.+:tests"
40
40
  testCompile "org.mockito:mockito-core:1.9.5"
41
+ testCompile "com.github.tomakehurst:wiremock-jre8:2.25.1"
41
42
  }
42
43
 
43
44
  javadoc {
@@ -1,7 +1,7 @@
1
1
 
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = "embulk-output-td"
4
- spec.version = "0.5.2"
4
+ spec.version = "0.5.3"
5
5
  spec.authors = ["Muga Nishizawa"]
6
6
  spec.summary = %[TreasureData output plugin for Embulk]
7
7
  spec.description = %[TreasureData output plugin is an Embulk plugin that loads records to TreasureData read by any input plugins. Search the input plugins by 'embulk-output' keyword.]
@@ -1,29 +1,14 @@
1
1
  package org.embulk.output.td;
2
2
 
3
- import java.io.IOException;
4
- import java.io.InputStream;
5
- import java.util.LinkedHashMap;
6
- import java.util.List;
7
- import java.util.ArrayList;
8
- import java.util.Map;
9
- import java.util.HashMap;
10
- import java.nio.charset.StandardCharsets;
11
- import java.util.Properties;
12
- import java.util.UUID;
13
- import java.util.regex.Pattern;
14
- import java.util.zip.GZIPInputStream;
15
-
16
- import javax.validation.constraints.Min;
17
- import javax.validation.constraints.Max;
18
-
3
+ import com.fasterxml.jackson.annotation.JsonCreator;
4
+ import com.fasterxml.jackson.annotation.JsonValue;
19
5
  import com.google.common.annotations.VisibleForTesting;
20
6
  import com.google.common.base.Function;
21
7
  import com.google.common.base.Optional;
22
- import com.google.common.base.Predicates;
23
8
  import com.google.common.base.Throwables;
9
+ import com.google.common.collect.ArrayListMultimap;
24
10
  import com.google.common.collect.Lists;
25
- import com.fasterxml.jackson.annotation.JsonCreator;
26
- import com.fasterxml.jackson.annotation.JsonValue;
11
+ import com.google.common.collect.Multimap;
27
12
  import com.treasuredata.client.ProxyConfig;
28
13
  import com.treasuredata.client.TDClient;
29
14
  import com.treasuredata.client.TDClientBuilder;
@@ -35,22 +20,22 @@ import com.treasuredata.client.model.TDColumn;
35
20
  import com.treasuredata.client.model.TDColumnType;
36
21
  import com.treasuredata.client.model.TDTable;
37
22
  import org.embulk.EmbulkVersion;
38
- import org.embulk.config.TaskReport;
39
23
  import org.embulk.config.Config;
40
24
  import org.embulk.config.ConfigDefault;
41
25
  import org.embulk.config.ConfigDiff;
42
- import org.embulk.config.ConfigSource;
43
26
  import org.embulk.config.ConfigException;
27
+ import org.embulk.config.ConfigSource;
44
28
  import org.embulk.config.Task;
29
+ import org.embulk.config.TaskReport;
45
30
  import org.embulk.config.TaskSource;
46
31
  import org.embulk.output.td.writer.FieldWriterSet;
32
+ import org.embulk.spi.Column;
33
+ import org.embulk.spi.ColumnVisitor;
47
34
  import org.embulk.spi.DataException;
48
35
  import org.embulk.spi.Exec;
49
- import org.embulk.spi.ColumnVisitor;
50
36
  import org.embulk.spi.ExecSession;
51
37
  import org.embulk.spi.OutputPlugin;
52
38
  import org.embulk.spi.Schema;
53
- import org.embulk.spi.Column;
54
39
  import org.embulk.spi.TransactionalPageOutput;
55
40
  import org.embulk.spi.time.Timestamp;
56
41
  import org.embulk.spi.time.TimestampFormatter;
@@ -60,6 +45,21 @@ import org.msgpack.core.MessageUnpacker;
60
45
  import org.msgpack.value.Value;
61
46
  import org.slf4j.Logger;
62
47
 
48
+ import javax.validation.constraints.Max;
49
+ import javax.validation.constraints.Min;
50
+ import java.io.IOException;
51
+ import java.io.InputStream;
52
+ import java.nio.charset.StandardCharsets;
53
+ import java.util.ArrayList;
54
+ import java.util.HashMap;
55
+ import java.util.LinkedHashMap;
56
+ import java.util.List;
57
+ import java.util.Map;
58
+ import java.util.Properties;
59
+ import java.util.UUID;
60
+ import java.util.regex.Pattern;
61
+ import java.util.zip.GZIPInputStream;
62
+
63
63
  import static com.google.common.base.Optional.fromNullable;
64
64
  import static java.lang.Integer.parseInt;
65
65
 
@@ -70,74 +70,74 @@ public class TdOutputPlugin
70
70
  extends Task, TimestampFormatter.Task
71
71
  {
72
72
  @Config("apikey")
73
- public String getApiKey();
73
+ String getApiKey();
74
74
 
75
75
  @Config("endpoint")
76
76
  @ConfigDefault("\"api.treasuredata.com\"")
77
- public String getEndpoint();
77
+ String getEndpoint();
78
78
 
79
79
  @Config("use_ssl")
80
80
  @ConfigDefault("true")
81
- public boolean getUseSsl();
81
+ boolean getUseSsl();
82
82
 
83
83
  @Config("http_proxy")
84
84
  @ConfigDefault("null")
85
- public Optional<HttpProxyTask> getHttpProxy();
85
+ Optional<HttpProxyTask> getHttpProxy();
86
86
 
87
87
  // TODO connect_timeout, read_timeout, send_timeout
88
88
 
89
89
  @Config("mode")
90
90
  @ConfigDefault("\"append\"")
91
- public Mode getMode();
91
+ Mode getMode();
92
92
 
93
93
  @Config("auto_create_table")
94
94
  @ConfigDefault("true")
95
- public boolean getAutoCreateTable();
95
+ boolean getAutoCreateTable();
96
96
 
97
97
  @Config("database")
98
- public String getDatabase();
98
+ String getDatabase();
99
99
 
100
100
  @Config("table")
101
- public String getTable();
101
+ String getTable();
102
102
 
103
- public void setLoadTargetTableName(String name);
104
- public String getLoadTargetTableName();
103
+ void setLoadTargetTableName(String name);
104
+ String getLoadTargetTableName();
105
105
 
106
106
  @Config("session")
107
107
  @ConfigDefault("null")
108
- public Optional<String> getSession();
108
+ Optional<String> getSession();
109
109
 
110
110
  @Config("default_timestamp_type_convert_to")
111
111
  @ConfigDefault("\"string\"")
112
- public ConvertTimestampType getConvertTimestampType();
112
+ ConvertTimestampType getConvertTimestampType();
113
113
 
114
114
  @Config("time_column")
115
115
  @ConfigDefault("null")
116
- public Optional<String> getTimeColumn();
116
+ Optional<String> getTimeColumn();
117
117
 
118
118
  @Config("time_value")
119
119
  @ConfigDefault("null")
120
- public Optional<TimeValueConfig> getTimeValue(); // TODO allow timestamp format such as {from: "2015-01-01 00:00:00 UTC", to: "2015-01-02 00:00:00 UTC"} as well as unixtime integer
121
- public void setTimeValue(Optional<TimeValueConfig> timeValue);
120
+ Optional<TimeValueConfig> getTimeValue(); // TODO allow timestamp format such as {from: "2015-01-01 00:00:00 UTC", to: "2015-01-02 00:00:00 UTC"} as well as unixtime integer
121
+ void setTimeValue(Optional<TimeValueConfig> timeValue);
122
122
 
123
123
  @Config("unix_timestamp_unit")
124
124
  @ConfigDefault("\"sec\"")
125
- public UnixTimestampUnit getUnixTimestampUnit();
125
+ UnixTimestampUnit getUnixTimestampUnit();
126
126
 
127
127
  @Config("tmpdir")
128
128
  @ConfigDefault("null")
129
- public Optional<String> getTempDir();
130
- public void setTempDir(Optional<String> dir);
129
+ Optional<String> getTempDir();
130
+ void setTempDir(Optional<String> dir);
131
131
 
132
132
  @Config("upload_concurrency")
133
133
  @ConfigDefault("2")
134
134
  @Min(1)
135
135
  @Max(8)
136
- public int getUploadConcurrency();
136
+ int getUploadConcurrency();
137
137
 
138
138
  @Config("file_split_size")
139
139
  @ConfigDefault("16384") // default 16MB (unit: kb)
140
- public long getFileSplitSize();
140
+ long getFileSplitSize();
141
141
 
142
142
  @Override
143
143
  @Config("default_timestamp_format")
@@ -153,11 +153,11 @@ public class TdOutputPlugin
153
153
  // * can parse SQL timestamp with microseconds like '2015-02-03 04:05:06.789012'
154
154
  // * can parse SQL timestamp with milliseconds like '2015-02-03 04:05:06.789'
155
155
  @ConfigDefault("\"%Y-%m-%d %H:%M:%S.%3N\"")
156
- public String getDefaultTimestampFormat();
156
+ String getDefaultTimestampFormat();
157
157
 
158
158
  @Config("column_options")
159
159
  @ConfigDefault("{}")
160
- public Map<String, TimestampColumnOption> getColumnOptions();
160
+ Map<String, TimestampColumnOption> getColumnOptions();
161
161
 
162
162
  @Config("stop_on_invalid_record")
163
163
  @ConfigDefault("false")
@@ -182,13 +182,22 @@ public class TdOutputPlugin
182
182
 
183
183
  @Config("pool_name")
184
184
  @ConfigDefault("null")
185
- public Optional<String> getPoolName();
185
+ Optional<String> getPoolName();
186
186
 
187
- public boolean getDoUpload();
188
- public void setDoUpload(boolean doUpload);
187
+ @Config("additional_http_headers")
188
+ @ConfigDefault("null")
189
+ Optional<Map<String, String>> getAdditionalHttpHeaders();
190
+
191
+ @Config("port")
192
+ @ConfigDefault("null")
193
+ Optional<Integer> getPort();
194
+ void setPort(Optional<Integer> port);
189
195
 
190
- public String getSessionName();
191
- public void setSessionName(String session);
196
+ boolean getDoUpload();
197
+ void setDoUpload(boolean doUpload);
198
+
199
+ String getSessionName();
200
+ void setSessionName(String session);
192
201
  }
193
202
 
194
203
  public interface TimestampColumnOption
@@ -234,22 +243,22 @@ public class TdOutputPlugin
234
243
  extends Task
235
244
  {
236
245
  @Config("host")
237
- public String getHost();
246
+ String getHost();
238
247
 
239
248
  @Config("port")
240
- public int getPort();
249
+ int getPort();
241
250
 
242
251
  @Config("use_ssl")
243
252
  @ConfigDefault("false")
244
- public boolean getUseSsl();
253
+ boolean getUseSsl();
245
254
 
246
255
  @Config("user")
247
256
  @ConfigDefault("null")
248
- public Optional<String> getUser();
257
+ Optional<String> getUser();
249
258
 
250
259
  @Config("password")
251
260
  @ConfigDefault("null")
252
- public Optional<String> getPassword();
261
+ Optional<String> getPassword();
253
262
  }
254
263
 
255
264
  public static enum ConvertTimestampType
@@ -476,6 +485,14 @@ public class TdOutputPlugin
476
485
  builder.setRetryInitialIntervalMillis(task.getRetryInitialIntervalMillis());
477
486
  builder.setRetryMaxIntervalMillis(task.getRetryMaxIntervalMillis());
478
487
 
488
+ if (task.getPort().isPresent()) {
489
+ builder.setPort(task.getPort().get());
490
+ }
491
+
492
+ if (task.getAdditionalHttpHeaders().isPresent()) {
493
+ builder.setHeaders(buildMultiMapHeaders(task.getAdditionalHttpHeaders().get()));
494
+ }
495
+
479
496
  Optional<ProxyConfig> proxyConfig = newProxyConfig(task.getHttpProxy());
480
497
  if (proxyConfig.isPresent()) {
481
498
  builder.setProxy(proxyConfig.get());
@@ -484,6 +501,15 @@ public class TdOutputPlugin
484
501
  return builder.build();
485
502
  }
486
503
 
504
+ private Multimap<String, String> buildMultiMapHeaders(Map<String, String> headers)
505
+ {
506
+ Multimap<String, String> multimap = ArrayListMultimap.create();
507
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
508
+ multimap.put(entry.getKey(), entry.getValue());
509
+ }
510
+ return multimap;
511
+ }
512
+
487
513
  @VisibleForTesting
488
514
  Optional<ProxyConfig> newProxyConfig(Optional<HttpProxyTask> task)
489
515
  {
@@ -776,7 +802,7 @@ public class TdOutputPlugin
776
802
  try {
777
803
  return client.showTable(databaseName, tableName);
778
804
  }
779
- catch(TDClientHttpNotFoundException e) {
805
+ catch (TDClientHttpNotFoundException e) {
780
806
  return null;
781
807
  }
782
808
  }
@@ -1,5 +1,6 @@
1
1
  package org.embulk.output.td;
2
2
 
3
+ import com.github.tomakehurst.wiremock.junit.WireMockRule;
3
4
  import com.google.common.base.Optional;
4
5
  import com.google.common.collect.ImmutableMap;
5
6
  import com.google.common.collect.Lists;
@@ -13,14 +14,16 @@ import com.treasuredata.client.model.TDColumn;
13
14
  import com.treasuredata.client.model.TDColumnType;
14
15
  import com.treasuredata.client.model.TDTable;
15
16
  import com.treasuredata.client.model.TDTableType;
17
+ import org.apache.http.Header;
18
+ import org.apache.http.message.BasicHeader;
16
19
  import org.embulk.EmbulkTestRuntime;
17
- import org.embulk.config.TaskReport;
18
20
  import org.embulk.config.ConfigDiff;
19
21
  import org.embulk.config.ConfigException;
20
22
  import org.embulk.config.ConfigSource;
23
+ import org.embulk.config.TaskReport;
21
24
  import org.embulk.config.TaskSource;
22
- import org.embulk.output.td.TdOutputPlugin.PluginTask;
23
25
  import org.embulk.output.td.TdOutputPlugin.HttpProxyTask;
26
+ import org.embulk.output.td.TdOutputPlugin.PluginTask;
24
27
  import org.embulk.output.td.TdOutputPlugin.TimestampColumnOption;
25
28
  import org.embulk.output.td.TdOutputPlugin.UnixTimestampUnit;
26
29
  import org.embulk.output.td.writer.FieldWriterSet;
@@ -39,10 +42,18 @@ import org.junit.Test;
39
42
  import org.mockito.ArgumentCaptor;
40
43
  import org.slf4j.Logger;
41
44
 
42
- import java.util.ArrayList;
43
45
  import java.util.HashMap;
44
46
  import java.util.List;
45
-
47
+ import java.util.Map;
48
+
49
+ import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
50
+ import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
51
+ import static com.github.tomakehurst.wiremock.client.WireMock.get;
52
+ import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
53
+ import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
54
+ import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
55
+ import static com.github.tomakehurst.wiremock.client.WireMock.verify;
56
+ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
46
57
  import static com.treasuredata.client.model.TDBulkImportSession.ImportStatus.COMMITTED;
47
58
  import static com.treasuredata.client.model.TDBulkImportSession.ImportStatus.COMMITTING;
48
59
  import static com.treasuredata.client.model.TDBulkImportSession.ImportStatus.PERFORMING;
@@ -56,7 +67,6 @@ import static org.junit.Assert.fail;
56
67
  import static org.mockito.Matchers.any;
57
68
  import static org.mockito.Matchers.anyInt;
58
69
  import static org.mockito.Matchers.anyString;
59
- import static org.mockito.Mockito.doAnswer;
60
70
  import static org.mockito.Mockito.doNothing;
61
71
  import static org.mockito.Mockito.doReturn;
62
72
  import static org.mockito.Mockito.doThrow;
@@ -68,6 +78,11 @@ public class TestTdOutputPlugin
68
78
  @Rule
69
79
  public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
70
80
 
81
+ private final int wireMockPort = 10888;
82
+
83
+ @Rule
84
+ public WireMockRule wireMockRule = new WireMockRule(options().port(wireMockPort), false);
85
+
71
86
  private ConfigSource config; // not mock
72
87
  private TdOutputPlugin plugin; // mock
73
88
 
@@ -567,7 +582,7 @@ public class TestTdOutputPlugin
567
582
  ArgumentCaptor<List<TDColumn>> schemaCaptor = ArgumentCaptor.forClass((Class) List.class);
568
583
  doNothing().when(client).appendTableSchema(anyString(), anyString(), schemaCaptor.capture());
569
584
 
570
- plugin.updateSchema(client, schema,task);
585
+ plugin.updateSchema(client, schema, task);
571
586
 
572
587
  List<Column> inputCols = schema.getColumns();
573
588
  List<TDColumn> uploadedCols = schemaCaptor.getValue();
@@ -577,6 +592,51 @@ public class TestTdOutputPlugin
577
592
  assertEquals(inputCols.get(2).getName(), uploadedCols.get(2).getName());
578
593
  }
579
594
 
595
+ @Test
596
+ public void testTDClientSendsExtraHeader()
597
+ {
598
+ final String urlRegx = "/v3/table/show/.*";
599
+ final Header header1 = new BasicHeader("h_name", "h_value");
600
+ final Header header2 = new BasicHeader("ABC", "XYZ");
601
+ final Map<String, String> headers = ImmutableMap.of(
602
+ header1.getName(), header1.getValue(),
603
+ header2.getName(), header2.getValue());
604
+
605
+ PluginTask task = config()
606
+ .set("endpoint", "localhost")
607
+ .set("port", wireMockPort)
608
+ .set("use_ssl", "false") // ssl disabled for wiremock
609
+ .set("additional_http_headers", headers)
610
+ .loadConfig(PluginTask.class);
611
+
612
+ stubFor(get(urlMatching(urlRegx))
613
+ .willReturn(aResponse()
614
+ .withBody("{\n" +
615
+ " \"id\": 46732,\n" +
616
+ " \"name\": \"sample_csv11\",\n" +
617
+ " \"estimated_storage_size\": 0,\n" +
618
+ " \"counter_updated_at\": null,\n" +
619
+ " \"last_log_timestamp\": null,\n" +
620
+ " \"delete_protected\": false,\n" +
621
+ " \"created_at\": \"2019-10-23 07:49:02 UTC\",\n" +
622
+ " \"updated_at\": \"2019-10-23 07:51:13 UTC\",\n" +
623
+ " \"type\": \"log\",\n" +
624
+ " \"include_v\": true,\n" +
625
+ " \"count\": 15,\n" +
626
+ " \"schema\": \"[]\",\n" +
627
+ " \"expire_days\": null\n" +
628
+ "}")));
629
+
630
+ TDClient client = plugin.newTDClient(task);
631
+
632
+ // issue an API request
633
+ plugin.validateTableExists(client, "tmp_db", "tmp_table");
634
+
635
+ verify(getRequestedFor(urlMatching(urlRegx))
636
+ .withHeader(header1.getName(), equalTo(header1.getValue()))
637
+ .withHeader(header2.getName(), equalTo(header2.getValue())));
638
+ }
639
+
580
640
  public static ConfigSource config()
581
641
  {
582
642
  return Exec.newConfigSource()
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-output-td
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muga Nishizawa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-24 00:00:00.000000000 Z
11
+ date: 2020-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -96,7 +96,7 @@ files:
96
96
  - classpath/hamcrest-core-1.1.jar
97
97
  - classpath/jackson-datatype-json-org-2.8.1.jar
98
98
  - classpath/td-client-0.8.4.jar
99
- - classpath/embulk-output-td-0.5.2.jar
99
+ - classpath/embulk-output-td-0.5.3.jar
100
100
  - classpath/okio-1.13.0.jar
101
101
  homepage: https://github.com/treasure-data/embulk-output-td
102
102
  licenses: