embulk-output-kintone 0.4.0 → 0.4.1
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/.github/workflows/ci.yml +1 -0
- data/.gitignore +0 -1
- data/build.gradle +18 -19
- data/classpath/embulk-output-kintone-0.4.1.jar +0 -0
- data/classpath/shadow-kintone-java-client-0.4.1-all.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.properties +1 -1
- data/settings.gradle +2 -0
- data/shadow-kintone-java-client/build.gradle +35 -0
- data/src/main/java/org/embulk/output/kintone/KintonePageOutput.java +166 -121
- data/src/main/java/org/embulk/output/kintone/KintoneRetryOption.java +19 -0
- data/src/main/java/org/embulk/output/kintone/PluginTask.java +3 -3
- data/src/test/java/com/kintone/client/Json.java +16 -0
- data/src/test/java/org/embulk/output/kintone/KintoneColumnOptionBuilder.java +63 -0
- data/src/test/java/org/embulk/output/kintone/KintoneColumnVisitorTest.java +297 -0
- data/src/test/java/org/embulk/output/kintone/KintoneColumnVisitorVerifier.java +52 -0
- data/src/test/java/org/embulk/output/kintone/KintonePageOutputVerifier.java +226 -0
- data/src/test/java/org/embulk/output/kintone/OutputPageBuilder.java +92 -0
- data/src/test/java/org/embulk/output/kintone/TestKintoneOutputPlugin.java +163 -1
- data/src/test/java/org/embulk/output/kintone/TestTask.java +40 -0
- data/src/test/java/org/embulk/output/kintone/TestTaskMode.java +31 -0
- data/src/test/resources/logback-test.xml +14 -0
- data/src/test/resources/org/embulk/output/kintone/config.yml +4 -0
- data/src/test/resources/org/embulk/output/kintone/task/config.yml +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/config.yml +54 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/input.csv +7 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/insert_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/update_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/upsert_add_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/upsert_update_records.jsonl +4 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/values.json +1 -0
- metadata +25 -3
- data/classpath/embulk-output-kintone-0.4.0.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: c677006a4f3dfdbec29c97e039045874614b3e99
|
4
|
+
data.tar.gz: 9c1fff33d958a4ee8be940da64cc7e10af04eb92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6e53840dad2b56c75e7422a769f0ae2eb8b24ce6034cc269255952e22442c77164c3bdac78a08f28086e5318df2318f99ad924d1bd85af8966ae83e5d57d627
|
7
|
+
data.tar.gz: 641e40a2986787204ef8e0feec1b916a2d4d0b5c0cc1d5e9d0137f38eaf8ed43b3b5b0b2f19f3304ee8736668b049d0a115836a62d8d3cd6efa20fe61ecc3be5
|
data/.github/workflows/ci.yml
CHANGED
data/.gitignore
CHANGED
data/build.gradle
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
plugins {
|
2
2
|
id "com.jfrog.bintray" version "1.1"
|
3
3
|
id "com.github.jruby-gradle.base" version "1.5.0"
|
4
|
-
id "com.github.johnrengelman.shadow" version "
|
4
|
+
id "com.github.johnrengelman.shadow" version "6.1.0" apply false
|
5
5
|
id "java"
|
6
6
|
id "checkstyle"
|
7
7
|
id "com.palantir.git-version" version "0.12.3"
|
@@ -12,9 +12,6 @@ repositories {
|
|
12
12
|
mavenCentral()
|
13
13
|
jcenter()
|
14
14
|
}
|
15
|
-
configurations {
|
16
|
-
provided
|
17
|
-
}
|
18
15
|
|
19
16
|
version = {
|
20
17
|
def vd = versionDetails()
|
@@ -29,26 +26,23 @@ version = {
|
|
29
26
|
sourceCompatibility = 1.8
|
30
27
|
targetCompatibility = 1.8
|
31
28
|
|
32
|
-
shadowJar {
|
33
|
-
exclude "org/embulk/plugin/**"
|
34
|
-
relocate "com.fasterxml.jackson", "embulk.kintone.com.fasterxml.jackson"
|
35
|
-
}
|
36
|
-
|
37
29
|
dependencies {
|
38
|
-
|
39
|
-
|
40
|
-
compile "com.kintone:kintone-java-client:1.0.2"
|
30
|
+
compileOnly "org.embulk:embulk-core:0.9.23"
|
31
|
+
implementation project(path: ":shadow-kintone-java-client", configuration: "shadow")
|
41
32
|
|
42
|
-
|
43
|
-
|
33
|
+
testImplementation "junit:junit:4.+"
|
34
|
+
testImplementation "org.embulk:embulk-test:0.9.23"
|
35
|
+
testImplementation "org.embulk:embulk-standards:0.9.23"
|
36
|
+
testImplementation "org.embulk:embulk-deps-buffer:0.9.23"
|
37
|
+
testImplementation "org.embulk:embulk-deps-config:0.9.23"
|
38
|
+
testImplementation "org.mockito:mockito-inline:4.11.0"
|
39
|
+
testImplementation "ch.qos.logback:logback-classic:1.3.8"
|
40
|
+
testImplementation "net.jcip:jcip-annotations:1.0"
|
44
41
|
}
|
45
42
|
|
46
|
-
task classpath(type: Copy, dependsOn: ["jar"
|
43
|
+
task classpath(type: Copy, dependsOn: ["jar"]) {
|
47
44
|
doFirst { file("classpath").deleteDir() }
|
48
|
-
from (configurations.
|
49
|
-
+ configurations.shadow
|
50
|
-
- files(shadowJar.getIncludedDependencies())
|
51
|
-
+ files(shadowJar.archivePath))
|
45
|
+
from (configurations.runtimeClasspath + files(jar.archivePath))
|
52
46
|
into "classpath"
|
53
47
|
}
|
54
48
|
clean { delete "classpath" }
|
@@ -127,3 +121,8 @@ spotless {
|
|
127
121
|
toggleOffOn()
|
128
122
|
}
|
129
123
|
}
|
124
|
+
|
125
|
+
test {
|
126
|
+
forkEvery = 1
|
127
|
+
maxHeapSize = "1g"
|
128
|
+
}
|
Binary file
|
Binary file
|
@@ -1,5 +1,5 @@
|
|
1
1
|
distributionBase=GRADLE_USER_HOME
|
2
2
|
distributionPath=wrapper/dists
|
3
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.
|
3
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.2-bin.zip
|
4
4
|
zipStoreBase=GRADLE_USER_HOME
|
5
5
|
zipStorePath=wrapper/dists
|
data/settings.gradle
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
plugins {
|
2
|
+
id "java"
|
3
|
+
id "maven-publish"
|
4
|
+
id "com.github.johnrengelman.shadow"
|
5
|
+
}
|
6
|
+
|
7
|
+
repositories {
|
8
|
+
mavenCentral()
|
9
|
+
}
|
10
|
+
|
11
|
+
group = "${rootProject.group}"
|
12
|
+
version = "${rootProject.version}"
|
13
|
+
|
14
|
+
sourceCompatibility = 1.8
|
15
|
+
targetCompatibility = 1.8
|
16
|
+
|
17
|
+
configurations {
|
18
|
+
runtimeClasspath {
|
19
|
+
resolutionStrategy.activateDependencyLocking()
|
20
|
+
}
|
21
|
+
shadow {
|
22
|
+
resolutionStrategy.activateDependencyLocking()
|
23
|
+
transitive = false
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
dependencies {
|
28
|
+
implementation("com.kintone:kintone-java-client:1.4.0") {
|
29
|
+
exclude group: "org.slf4j", module: "slf4j-api"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
shadowJar {
|
34
|
+
relocate "com.fasterxml.jackson", "embulk.kintone.com.fasterxml.jackson"
|
35
|
+
}
|
@@ -1,18 +1,23 @@
|
|
1
1
|
package org.embulk.output.kintone;
|
2
2
|
|
3
|
+
import static org.embulk.spi.util.RetryExecutor.retryExecutor;
|
4
|
+
|
5
|
+
import com.fasterxml.jackson.databind.JsonNode;
|
6
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
3
7
|
import com.kintone.client.KintoneClient;
|
4
8
|
import com.kintone.client.KintoneClientBuilder;
|
5
9
|
import com.kintone.client.api.record.GetRecordsByCursorResponseBody;
|
10
|
+
import com.kintone.client.exception.KintoneApiRuntimeException;
|
6
11
|
import com.kintone.client.model.record.FieldType;
|
7
12
|
import com.kintone.client.model.record.Record;
|
8
13
|
import com.kintone.client.model.record.RecordForUpdate;
|
9
14
|
import com.kintone.client.model.record.UpdateKey;
|
15
|
+
import java.io.IOException;
|
10
16
|
import java.math.BigDecimal;
|
11
17
|
import java.util.ArrayList;
|
12
18
|
import java.util.Arrays;
|
13
19
|
import java.util.Collections;
|
14
20
|
import java.util.List;
|
15
|
-
import java.util.concurrent.TimeUnit;
|
16
21
|
import java.util.stream.Collectors;
|
17
22
|
import org.embulk.config.ConfigException;
|
18
23
|
import org.embulk.config.TaskReport;
|
@@ -22,6 +27,8 @@ import org.embulk.spi.Page;
|
|
22
27
|
import org.embulk.spi.PageReader;
|
23
28
|
import org.embulk.spi.Schema;
|
24
29
|
import org.embulk.spi.TransactionalPageOutput;
|
30
|
+
import org.embulk.spi.util.RetryExecutor.RetryGiveupException;
|
31
|
+
import org.embulk.spi.util.RetryExecutor.Retryable;
|
25
32
|
import org.slf4j.Logger;
|
26
33
|
import org.slf4j.LoggerFactory;
|
27
34
|
|
@@ -29,6 +36,12 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
29
36
|
public static final int UPSERT_BATCH_SIZE = 10000;
|
30
37
|
public static final int CHUNK_SIZE = 100;
|
31
38
|
private static final Logger LOGGER = LoggerFactory.getLogger(KintonePageOutput.class);
|
39
|
+
private static final List<String> RETRYABLE_ERROR_CODES =
|
40
|
+
Arrays.asList(
|
41
|
+
"GAIA_TM12", // 作成できるカーソルの上限に達しているため、カーソ ルを作成できません。不要なカーソルを削除するか、しばらく経ってから再実行してください。
|
42
|
+
"GAIA_RE18", // データベースのロックに失敗したため、変更を保存できませんでした。時間をおいて再度お試しください。
|
43
|
+
"GAIA_DA02" // データベースのロックに失敗したため、変更を保存できませんでした。時間をおいて再度お試しください。
|
44
|
+
);
|
32
45
|
private final PageReader pageReader;
|
33
46
|
private final PluginTask task;
|
34
47
|
private KintoneClient client;
|
@@ -104,133 +117,176 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
104
117
|
}
|
105
118
|
}
|
106
119
|
|
120
|
+
private void update(ArrayList<RecordForUpdate> records) {
|
121
|
+
execute(
|
122
|
+
client -> {
|
123
|
+
client.record().updateRecords(task.getAppId(), records);
|
124
|
+
});
|
125
|
+
}
|
126
|
+
|
127
|
+
private void insert(ArrayList<Record> records) {
|
128
|
+
execute(
|
129
|
+
client -> {
|
130
|
+
client.record().addRecords(task.getAppId(), records);
|
131
|
+
});
|
132
|
+
}
|
133
|
+
|
107
134
|
private void execute(Consumer<KintoneClient> operation) {
|
108
135
|
connect(task);
|
109
|
-
if (this.client
|
110
|
-
operation.accept(this.client);
|
111
|
-
} else {
|
136
|
+
if (this.client == null) {
|
112
137
|
throw new RuntimeException("Failed to connect to kintone.");
|
113
138
|
}
|
139
|
+
KintoneRetryOption retryOption = task.getRetryOptions();
|
140
|
+
try {
|
141
|
+
retryExecutor()
|
142
|
+
.withRetryLimit(retryOption.getLimit())
|
143
|
+
.withInitialRetryWait(retryOption.getInitialWaitMillis())
|
144
|
+
.withMaxRetryWait(retryOption.getMaxWaitMillis())
|
145
|
+
.runInterruptible(
|
146
|
+
new Retryable<Void>() {
|
147
|
+
|
148
|
+
@Override
|
149
|
+
public Void call() throws Exception {
|
150
|
+
operation.accept(client);
|
151
|
+
return null;
|
152
|
+
}
|
153
|
+
|
154
|
+
@Override
|
155
|
+
public boolean isRetryableException(Exception e) {
|
156
|
+
if (!(e instanceof KintoneApiRuntimeException)) {
|
157
|
+
return false;
|
158
|
+
}
|
159
|
+
|
160
|
+
try {
|
161
|
+
ObjectMapper mapper = new ObjectMapper();
|
162
|
+
JsonNode content =
|
163
|
+
mapper.readTree(((KintoneApiRuntimeException) e).getContent());
|
164
|
+
String code = content.get("code").textValue();
|
165
|
+
return RETRYABLE_ERROR_CODES.contains(code);
|
166
|
+
} catch (IOException ex) {
|
167
|
+
throw new RuntimeException(ex);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
@Override
|
172
|
+
public void onRetry(
|
173
|
+
Exception exception, int retryCount, int retryLimit, int retryWait)
|
174
|
+
throws RetryGiveupException {
|
175
|
+
String message =
|
176
|
+
String.format(
|
177
|
+
"Retrying %d/%d after %d seconds. Message: %s",
|
178
|
+
retryCount, retryLimit, retryWait / 1000, exception.getMessage());
|
179
|
+
if (retryCount % 3 == 0) {
|
180
|
+
LOGGER.warn(message, exception);
|
181
|
+
} else {
|
182
|
+
LOGGER.warn(message);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
@Override
|
187
|
+
public void onGiveup(Exception firstException, Exception lastException)
|
188
|
+
throws RetryGiveupException {}
|
189
|
+
});
|
190
|
+
} catch (RetryGiveupException | InterruptedException e) {
|
191
|
+
throw new RuntimeException("kintone throw exception", e);
|
192
|
+
}
|
114
193
|
}
|
115
194
|
|
116
195
|
private void insertPage(final Page page) {
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
}
|
138
|
-
if (records.size() > 0) {
|
139
|
-
client.record().addRecords(task.getAppId(), records);
|
140
|
-
}
|
141
|
-
} catch (Exception e) {
|
142
|
-
throw new RuntimeException("kintone throw exception", e);
|
143
|
-
}
|
144
|
-
});
|
196
|
+
|
197
|
+
ArrayList<Record> records = new ArrayList<>();
|
198
|
+
pageReader.setPage(page);
|
199
|
+
KintoneColumnVisitor visitor = new KintoneColumnVisitor(pageReader, task.getColumnOptions());
|
200
|
+
while (pageReader.nextRecord()) {
|
201
|
+
Record record = new Record();
|
202
|
+
visitor.setRecord(record);
|
203
|
+
for (Column column : pageReader.getSchema().getColumns()) {
|
204
|
+
column.visit(visitor);
|
205
|
+
}
|
206
|
+
|
207
|
+
records.add(record);
|
208
|
+
if (records.size() == CHUNK_SIZE) {
|
209
|
+
insert(records);
|
210
|
+
records.clear();
|
211
|
+
}
|
212
|
+
}
|
213
|
+
if (records.size() > 0) {
|
214
|
+
insert(records);
|
215
|
+
}
|
145
216
|
}
|
146
217
|
|
147
218
|
private void updatePage(final Page page) {
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
}
|
181
|
-
}
|
182
|
-
if (updateRecords.size() > 0) {
|
183
|
-
client.record().updateRecords(task.getAppId(), updateRecords);
|
184
|
-
}
|
185
|
-
} catch (Exception e) {
|
186
|
-
throw new RuntimeException("kintone throw exception", e);
|
187
|
-
}
|
188
|
-
});
|
219
|
+
ArrayList<RecordForUpdate> updateRecords = new ArrayList<>();
|
220
|
+
pageReader.setPage(page);
|
221
|
+
|
222
|
+
KintoneColumnVisitor visitor =
|
223
|
+
new KintoneColumnVisitor(
|
224
|
+
pageReader,
|
225
|
+
task.getColumnOptions(),
|
226
|
+
task.getUpdateKeyName()
|
227
|
+
.orElseThrow(() -> new RuntimeException("unreachable"))); // Already validated
|
228
|
+
while (pageReader.nextRecord()) {
|
229
|
+
Record record = new Record();
|
230
|
+
UpdateKey updateKey = new UpdateKey();
|
231
|
+
visitor.setRecord(record);
|
232
|
+
visitor.setUpdateKey(updateKey);
|
233
|
+
for (Column column : pageReader.getSchema().getColumns()) {
|
234
|
+
column.visit(visitor);
|
235
|
+
}
|
236
|
+
|
237
|
+
if (updateKey.getValue() == "") {
|
238
|
+
continue;
|
239
|
+
}
|
240
|
+
|
241
|
+
record.removeField(updateKey.getField());
|
242
|
+
updateRecords.add(new RecordForUpdate(updateKey, record));
|
243
|
+
if (updateRecords.size() == CHUNK_SIZE) {
|
244
|
+
update(updateRecords);
|
245
|
+
updateRecords.clear();
|
246
|
+
}
|
247
|
+
}
|
248
|
+
if (updateRecords.size() > 0) {
|
249
|
+
update(updateRecords);
|
250
|
+
}
|
189
251
|
}
|
190
252
|
|
191
253
|
private void upsertPage(final Page page) {
|
192
254
|
execute(
|
193
255
|
client -> {
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
for (Column column : pageReader.getSchema().getColumns()) {
|
212
|
-
column.visit(visitor);
|
213
|
-
}
|
214
|
-
records.add(record);
|
215
|
-
updateKeys.add(updateKey);
|
216
|
-
|
217
|
-
if (records.size() == UPSERT_BATCH_SIZE) {
|
218
|
-
upsert(records, updateKeys);
|
219
|
-
records.clear();
|
220
|
-
updateKeys.clear();
|
221
|
-
}
|
256
|
+
ArrayList<Record> records = new ArrayList<>();
|
257
|
+
ArrayList<UpdateKey> updateKeys = new ArrayList<>();
|
258
|
+
pageReader.setPage(page);
|
259
|
+
|
260
|
+
KintoneColumnVisitor visitor =
|
261
|
+
new KintoneColumnVisitor(
|
262
|
+
pageReader,
|
263
|
+
task.getColumnOptions(),
|
264
|
+
task.getUpdateKeyName()
|
265
|
+
.orElseThrow(() -> new RuntimeException("unreachable"))); // Already validated
|
266
|
+
while (pageReader.nextRecord()) {
|
267
|
+
Record record = new Record();
|
268
|
+
UpdateKey updateKey = new UpdateKey();
|
269
|
+
visitor.setRecord(record);
|
270
|
+
visitor.setUpdateKey(updateKey);
|
271
|
+
for (Column column : pageReader.getSchema().getColumns()) {
|
272
|
+
column.visit(visitor);
|
222
273
|
}
|
223
|
-
|
274
|
+
records.add(record);
|
275
|
+
updateKeys.add(updateKey);
|
276
|
+
|
277
|
+
if (records.size() == UPSERT_BATCH_SIZE) {
|
224
278
|
upsert(records, updateKeys);
|
279
|
+
records.clear();
|
280
|
+
updateKeys.clear();
|
225
281
|
}
|
226
|
-
}
|
227
|
-
|
282
|
+
}
|
283
|
+
if (records.size() > 0) {
|
284
|
+
upsert(records, updateKeys);
|
228
285
|
}
|
229
286
|
});
|
230
287
|
}
|
231
288
|
|
232
|
-
private void upsert(ArrayList<Record> records, ArrayList<UpdateKey> updateKeys)
|
233
|
-
throws InterruptedException {
|
289
|
+
private void upsert(ArrayList<Record> records, ArrayList<UpdateKey> updateKeys) {
|
234
290
|
if (records.size() != updateKeys.size()) {
|
235
291
|
throw new RuntimeException("records.size() != updateKeys.size()");
|
236
292
|
}
|
@@ -274,20 +330,18 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
274
330
|
}
|
275
331
|
|
276
332
|
if (insertRecords.size() == CHUNK_SIZE) {
|
277
|
-
|
333
|
+
insert(insertRecords);
|
278
334
|
insertRecords.clear();
|
279
|
-
sleep();
|
280
335
|
} else if (updateRecords.size() == CHUNK_SIZE) {
|
281
|
-
|
336
|
+
update(updateRecords);
|
282
337
|
updateRecords.clear();
|
283
|
-
sleep();
|
284
338
|
}
|
285
339
|
}
|
286
340
|
if (insertRecords.size() > 0) {
|
287
|
-
|
341
|
+
insert(insertRecords);
|
288
342
|
}
|
289
343
|
if (updateRecords.size() > 0) {
|
290
|
-
|
344
|
+
update(updateRecords);
|
291
345
|
}
|
292
346
|
}
|
293
347
|
|
@@ -325,13 +379,4 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
325
379
|
private boolean existsRecord(List<String> distValues, UpdateKey updateKey) {
|
326
380
|
return distValues.stream().anyMatch(v -> v.equals(updateKey.getValue().toString()));
|
327
381
|
}
|
328
|
-
|
329
|
-
private void sleep() throws InterruptedException {
|
330
|
-
if (!task.getIntervalSeconds().isPresent()) {
|
331
|
-
return;
|
332
|
-
}
|
333
|
-
Integer interval = task.getIntervalSeconds().get();
|
334
|
-
LOGGER.info(String.format("sleep %d seconds.", interval));
|
335
|
-
TimeUnit.SECONDS.sleep(interval);
|
336
|
-
}
|
337
382
|
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package org.embulk.output.kintone;
|
2
|
+
|
3
|
+
import org.embulk.config.Config;
|
4
|
+
import org.embulk.config.ConfigDefault;
|
5
|
+
import org.embulk.config.Task;
|
6
|
+
|
7
|
+
public interface KintoneRetryOption extends Task {
|
8
|
+
@Config("limit")
|
9
|
+
@ConfigDefault("10")
|
10
|
+
Integer getLimit();
|
11
|
+
|
12
|
+
@Config("initial_wait_millis")
|
13
|
+
@ConfigDefault("1000")
|
14
|
+
Integer getInitialWaitMillis();
|
15
|
+
|
16
|
+
@Config("max_wait_millis")
|
17
|
+
@ConfigDefault("60000")
|
18
|
+
Integer getMaxWaitMillis();
|
19
|
+
}
|
@@ -49,7 +49,7 @@ public interface PluginTask extends Task {
|
|
49
49
|
@ConfigDefault("null")
|
50
50
|
Optional<String> getUpdateKeyName();
|
51
51
|
|
52
|
-
@Config("
|
53
|
-
@ConfigDefault("
|
54
|
-
|
52
|
+
@Config("retry_options")
|
53
|
+
@ConfigDefault("{}")
|
54
|
+
KintoneRetryOption getRetryOptions();
|
55
55
|
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
package com.kintone.client;
|
2
|
+
|
3
|
+
import java.io.ByteArrayInputStream;
|
4
|
+
import java.nio.charset.StandardCharsets;
|
5
|
+
|
6
|
+
public class Json {
|
7
|
+
private static final JsonMapper MAPPER = new JsonMapper();
|
8
|
+
|
9
|
+
public static String format(Object o) {
|
10
|
+
return new String(MAPPER.format(o), StandardCharsets.UTF_8);
|
11
|
+
}
|
12
|
+
|
13
|
+
public static <T> T parse(String s, Class<T> clazz) {
|
14
|
+
return MAPPER.parse(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)), clazz);
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
package org.embulk.output.kintone;
|
2
|
+
|
3
|
+
import java.util.Optional;
|
4
|
+
import org.embulk.config.TaskSource;
|
5
|
+
|
6
|
+
public class KintoneColumnOptionBuilder {
|
7
|
+
private String type;
|
8
|
+
private String fieldCode;
|
9
|
+
private String timezone;
|
10
|
+
private String valueSeparator;
|
11
|
+
|
12
|
+
public KintoneColumnOptionBuilder setType(String type) {
|
13
|
+
this.type = type;
|
14
|
+
return this;
|
15
|
+
}
|
16
|
+
|
17
|
+
public KintoneColumnOptionBuilder setFieldCode(String fieldCode) {
|
18
|
+
this.fieldCode = fieldCode;
|
19
|
+
return this;
|
20
|
+
}
|
21
|
+
|
22
|
+
public KintoneColumnOptionBuilder setTimezone(String timezone) {
|
23
|
+
this.timezone = timezone;
|
24
|
+
return this;
|
25
|
+
}
|
26
|
+
|
27
|
+
public KintoneColumnOptionBuilder setValueSeparator(String valueSeparator) {
|
28
|
+
this.valueSeparator = valueSeparator;
|
29
|
+
return this;
|
30
|
+
}
|
31
|
+
|
32
|
+
public KintoneColumnOption build() {
|
33
|
+
return new KintoneColumnOption() {
|
34
|
+
@Override
|
35
|
+
public String getType() {
|
36
|
+
return type;
|
37
|
+
}
|
38
|
+
|
39
|
+
@Override
|
40
|
+
public String getFieldCode() {
|
41
|
+
return fieldCode;
|
42
|
+
}
|
43
|
+
|
44
|
+
@Override
|
45
|
+
public Optional<String> getTimezone() {
|
46
|
+
return Optional.ofNullable(timezone);
|
47
|
+
}
|
48
|
+
|
49
|
+
@Override
|
50
|
+
public String getValueSeparator() {
|
51
|
+
return valueSeparator;
|
52
|
+
}
|
53
|
+
|
54
|
+
@Override
|
55
|
+
public void validate() {}
|
56
|
+
|
57
|
+
@Override
|
58
|
+
public TaskSource dump() {
|
59
|
+
return null;
|
60
|
+
}
|
61
|
+
};
|
62
|
+
}
|
63
|
+
}
|