embulk-output-kintone 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +65 -1
- data/build.gradle +1 -0
- data/classpath/commons-csv-1.9.0.jar +0 -0
- data/classpath/embulk-output-kintone-1.2.0.jar +0 -0
- data/classpath/externalsortinginjava-0.6.2.jar +0 -0
- data/classpath/{shadow-kintone-java-client-1.0.0-all.jar → shadow-kintone-java-client-1.2.0-all.jar} +0 -0
- data/src/main/java/org/embulk/output/kintone/KintoneClient.java +117 -0
- data/src/main/java/org/embulk/output/kintone/KintoneColumnOption.java +5 -0
- data/src/main/java/org/embulk/output/kintone/KintoneColumnType.java +226 -5
- data/src/main/java/org/embulk/output/kintone/KintoneColumnVisitor.java +82 -13
- data/src/main/java/org/embulk/output/kintone/KintoneMode.java +52 -4
- data/src/main/java/org/embulk/output/kintone/KintoneOutputPlugin.java +12 -20
- data/src/main/java/org/embulk/output/kintone/KintonePageOutput.java +123 -127
- data/src/main/java/org/embulk/output/kintone/KintoneSortColumn.java +33 -0
- data/src/main/java/org/embulk/output/kintone/PluginTask.java +32 -0
- data/src/main/java/org/embulk/output/kintone/deserializer/DeserializeApplier.java +19 -0
- data/src/main/java/org/embulk/output/kintone/deserializer/DeserializeException.java +7 -0
- data/src/main/java/org/embulk/output/kintone/deserializer/Deserializer.java +279 -0
- data/src/main/java/org/embulk/output/kintone/record/Id.java +18 -0
- data/src/main/java/org/embulk/output/kintone/record/IdOrUpdateKey.java +45 -0
- data/src/main/java/org/embulk/output/kintone/record/Skip.java +14 -0
- data/src/main/java/org/embulk/output/kintone/reducer/CSVInputColumnVisitor.java +78 -0
- data/src/main/java/org/embulk/output/kintone/reducer/CSVOutputColumnVisitor.java +79 -0
- data/src/main/java/org/embulk/output/kintone/reducer/ReduceException.java +11 -0
- data/src/main/java/org/embulk/output/kintone/reducer/ReduceType.java +190 -0
- data/src/main/java/org/embulk/output/kintone/reducer/ReducedPageOutput.java +100 -0
- data/src/main/java/org/embulk/output/kintone/reducer/Reducer.java +355 -0
- data/src/main/java/org/embulk/output/kintone/util/Lazy.java +20 -0
- data/src/test/java/org/embulk/output/kintone/KintoneClientTest.java +139 -0
- data/src/test/java/org/embulk/output/kintone/KintoneColumnOptionBuilder.java +7 -0
- data/src/test/java/org/embulk/output/kintone/KintoneColumnTypeTest.java +194 -0
- data/src/test/java/org/embulk/output/kintone/KintoneColumnVisitorTest.java +183 -64
- data/src/test/java/org/embulk/output/kintone/KintoneColumnVisitorVerifier.java +19 -9
- data/src/test/java/org/embulk/output/kintone/KintonePageOutputVerifier.java +120 -51
- data/src/test/java/org/embulk/output/kintone/MockClient.java +112 -0
- data/src/test/java/org/embulk/output/kintone/TestKintoneOutputPlugin.java +147 -22
- data/src/test/java/org/embulk/output/kintone/TestTaskMode.java +1 -0
- data/src/test/java/org/embulk/output/kintone/TestTaskReduce.java +47 -0
- data/src/test/java/org/embulk/output/kintone/TestTaskReduceException.java +50 -0
- data/src/test/java/org/embulk/output/kintone/TestTaskReduceSubtable.java +47 -0
- data/src/test/java/org/embulk/output/kintone/TestTaskSkip.java +80 -0
- data/src/test/java/org/embulk/output/kintone/TestTaskSkipId.java +80 -0
- data/src/test/java/org/embulk/output/kintone/deserializer/DeserializerTest.java +165 -0
- data/src/test/java/org/embulk/output/kintone/reducer/ReduceTypeTest.java +154 -0
- data/src/test/resources/org/embulk/output/kintone/client/config.yml +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/config.yml +2 -1
- data/src/test/resources/org/embulk/output/kintone/task/mode/config.yml +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/input.csv +7 -7
- data/src/test/resources/org/embulk/output/kintone/task/mode/insert_add_records.jsonl +6 -6
- data/src/test/resources/org/embulk/output/kintone/task/mode/{insert_add_ignore_nulls_records.jsonl → insert_ignore_nulls_add_records.jsonl} +2 -2
- data/src/test/resources/org/embulk/output/kintone/task/mode/{insert_add_prefer_nulls_records.jsonl → insert_prefer_nulls_add_records.jsonl} +6 -6
- data/src/test/resources/org/embulk/output/kintone/task/mode/{update_update_ignore_nulls_records.jsonl → update_ignore_nulls_update_records.jsonl} +2 -2
- data/src/test/resources/org/embulk/output/kintone/task/mode/{update_update_prefer_nulls_records.jsonl → update_prefer_nulls_update_records.jsonl} +3 -3
- data/src/test/resources/org/embulk/output/kintone/task/mode/update_update_records.jsonl +6 -6
- data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_add_records.jsonl → upsert_never_skip_add_records.jsonl} +2 -2
- data/src/test/resources/org/embulk/output/kintone/task/mode/upsert_never_skip_double_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_update_ignore_nulls_records.jsonl → upsert_never_skip_ignore_nulls_update_records.jsonl} +2 -2
- data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_add_prefer_nulls_records.jsonl → upsert_never_skip_prefer_nulls_add_records.jsonl} +3 -3
- data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_update_prefer_nulls_records.jsonl → upsert_never_skip_prefer_nulls_update_records.jsonl} +3 -3
- data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_update_records.jsonl → upsert_never_skip_update_records.jsonl} +4 -4
- data/src/test/resources/org/embulk/output/kintone/task/reduce/config.yml +171 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/input.csv +7 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/insert_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/insert_ignore_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/insert_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/update_ignore_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/update_prefer_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/update_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_add_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_double_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_double_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_ignore_nulls_add_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_ignore_nulls_double_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_ignore_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_prefer_nulls_add_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_prefer_nulls_double_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_prefer_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_update_records.jsonl +4 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/config.yml +36 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/derived_columns.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/input.csv +13 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/insert_add_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/update_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/config.yml +343 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/derived_columns.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/input.csv +13 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/insert_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/insert_ignore_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/insert_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/update_ignore_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/update_prefer_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/update_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_double_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_ignore_nulls_add_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_ignore_nulls_double_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_ignore_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_prefer_nulls_add_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_prefer_nulls_double_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_prefer_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/config.yml +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/input.csv +7 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/insert_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/insert_always_skip_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/insert_always_skip_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/insert_never_skip_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/insert_never_skip_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/insert_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_long_number_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_long_number_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_prefer_nulls_long_number_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_prefer_nulls_long_number_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_update_records.jsonl +5 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_never_skip_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_prefer_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/update_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_add_records.jsonl +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_prefer_nulls_string_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_prefer_nulls_string_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_string_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_string_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_add_records.jsonl +4 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_add_records.jsonl +4 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_string_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_string_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_string_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_string_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_add_records.jsonl +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_string_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_string_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_string_single_line_text_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_string_single_line_text_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/config.yml +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/input.csv +7 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_always_skip_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_always_skip_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_never_skip_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_never_skip_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_prefer_nulls_add_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_prefer_nulls__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_prefer_nulls__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_update_records.jsonl +5 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_never_skip_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_prefer_nulls_update_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_update_records.jsonl +6 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_prefer_nulls__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_prefer_nulls__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_update_records.jsonl +5 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_add_records.jsonl +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls_add_records.jsonl +4 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_update_records.jsonl +5 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls__id_add_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls__id_values.json +1 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls_add_records.jsonl +3 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls_update_records.jsonl +2 -0
- data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_update_records.jsonl +5 -0
- metadata +163 -17
- data/classpath/embulk-output-kintone-1.0.0.jar +0 -0
- /data/src/test/resources/org/embulk/output/kintone/task/mode/{values.json → upsert_never_skip_double_single_line_text_values.json} +0 -0
- /data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_add_ignore_nulls_records.jsonl → upsert_never_skip_ignore_nulls_add_records.jsonl} +0 -0
- /data/src/test/resources/org/embulk/output/kintone/task/mode/{values_ignore_nulls.json → upsert_never_skip_ignore_nulls_double_single_line_text_values.json} +0 -0
- /data/src/test/resources/org/embulk/output/kintone/task/mode/{values_prefer_nulls.json → upsert_never_skip_prefer_nulls_double_single_line_text_values.json} +0 -0
@@ -5,15 +5,11 @@ import static org.embulk.spi.util.RetryExecutor.retryExecutor;
|
|
5
5
|
import com.fasterxml.jackson.databind.JsonNode;
|
6
6
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
7
7
|
import com.google.common.collect.Maps;
|
8
|
-
import com.kintone.client.KintoneClient;
|
9
|
-
import com.kintone.client.KintoneClientBuilder;
|
10
8
|
import com.kintone.client.api.record.GetRecordsByCursorResponseBody;
|
11
9
|
import com.kintone.client.exception.KintoneApiRuntimeException;
|
12
|
-
import com.kintone.client.model.app.field.FieldProperty;
|
13
10
|
import com.kintone.client.model.record.FieldType;
|
14
11
|
import com.kintone.client.model.record.Record;
|
15
12
|
import com.kintone.client.model.record.RecordForUpdate;
|
16
|
-
import com.kintone.client.model.record.UpdateKey;
|
17
13
|
import java.io.IOException;
|
18
14
|
import java.lang.invoke.MethodHandles;
|
19
15
|
import java.math.BigDecimal;
|
@@ -28,8 +24,11 @@ import java.util.function.Function;
|
|
28
24
|
import java.util.function.Supplier;
|
29
25
|
import java.util.stream.Collectors;
|
30
26
|
import org.apache.commons.lang3.tuple.Pair;
|
31
|
-
import org.embulk.config.ConfigException;
|
32
27
|
import org.embulk.config.TaskReport;
|
28
|
+
import org.embulk.output.kintone.record.Id;
|
29
|
+
import org.embulk.output.kintone.record.IdOrUpdateKey;
|
30
|
+
import org.embulk.output.kintone.record.Skip;
|
31
|
+
import org.embulk.output.kintone.util.Lazy;
|
33
32
|
import org.embulk.spi.Exec;
|
34
33
|
import org.embulk.spi.Page;
|
35
34
|
import org.embulk.spi.PageReader;
|
@@ -50,34 +49,20 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
50
49
|
"GAIA_DA02" // データベースのロックに失敗したため、変更を保存できませんでした。時間をおいて再度お試しください。
|
51
50
|
);
|
52
51
|
private static final int UPSERT_BATCH_SIZE = 10000;
|
53
|
-
private static final int CHUNK_SIZE = 100;
|
54
52
|
private final Map<String, Pair<FieldType, FieldType>> wrongTypeFields = new TreeMap<>();
|
55
53
|
private final PluginTask task;
|
56
54
|
private final PageReader reader;
|
57
|
-
private KintoneClient client;
|
58
|
-
private Map<String, FieldProperty> formFields;
|
55
|
+
private final Lazy<KintoneClient> client;
|
59
56
|
|
60
57
|
public KintonePageOutput(PluginTask task, Schema schema) {
|
61
58
|
this.task = task;
|
62
59
|
reader = new PageReader(schema);
|
60
|
+
client = KintoneClient.lazy(() -> task, schema);
|
63
61
|
}
|
64
62
|
|
65
63
|
@Override
|
66
64
|
public void add(Page page) {
|
67
|
-
KintoneMode
|
68
|
-
switch (mode) {
|
69
|
-
case INSERT:
|
70
|
-
insertPage(page);
|
71
|
-
break;
|
72
|
-
case UPDATE:
|
73
|
-
updatePage(page);
|
74
|
-
break;
|
75
|
-
case UPSERT:
|
76
|
-
upsertPage(page);
|
77
|
-
break;
|
78
|
-
default:
|
79
|
-
throw new UnsupportedOperationException(String.format("Unknown mode '%s'", task.getMode()));
|
80
|
-
}
|
65
|
+
KintoneMode.of(task).add(page, task.getSkipIfNonExistingIdOrUpdateKey(), this);
|
81
66
|
}
|
82
67
|
|
83
68
|
@Override
|
@@ -87,14 +72,7 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
87
72
|
|
88
73
|
@Override
|
89
74
|
public void close() {
|
90
|
-
|
91
|
-
return; // Not connected
|
92
|
-
}
|
93
|
-
try {
|
94
|
-
client.close();
|
95
|
-
} catch (Exception e) {
|
96
|
-
throw new RuntimeException("kintone throw exception", e);
|
97
|
-
}
|
75
|
+
client.get().close();
|
98
76
|
}
|
99
77
|
|
100
78
|
@Override
|
@@ -113,38 +91,15 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
113
91
|
return Exec.newTaskReport();
|
114
92
|
}
|
115
93
|
|
116
|
-
public void connectIfNeeded() {
|
117
|
-
if (client != null) {
|
118
|
-
return; // Already connected
|
119
|
-
}
|
120
|
-
KintoneClientBuilder builder = KintoneClientBuilder.create("https://" + task.getDomain());
|
121
|
-
if (task.getGuestSpaceId().isPresent()) {
|
122
|
-
builder.setGuestSpaceId(task.getGuestSpaceId().get());
|
123
|
-
}
|
124
|
-
if (task.getBasicAuthUsername().isPresent() && task.getBasicAuthPassword().isPresent()) {
|
125
|
-
builder.withBasicAuth(task.getBasicAuthUsername().get(), task.getBasicAuthPassword().get());
|
126
|
-
}
|
127
|
-
if (task.getUsername().isPresent() && task.getPassword().isPresent()) {
|
128
|
-
builder.authByPassword(task.getUsername().get(), task.getPassword().get());
|
129
|
-
} else if (task.getToken().isPresent()) {
|
130
|
-
builder.authByApiToken(task.getToken().get());
|
131
|
-
} else {
|
132
|
-
throw new ConfigException("Username and password or token must be configured.");
|
133
|
-
}
|
134
|
-
client = builder.build();
|
135
|
-
formFields = client.app().getFormFields(task.getAppId());
|
136
|
-
}
|
137
|
-
|
138
94
|
private void insert(List<Record> records) {
|
139
|
-
executeWithRetry(() -> client.record().addRecords(task.getAppId(), records));
|
95
|
+
executeWithRetry(() -> client.get().record().addRecords(task.getAppId(), records));
|
140
96
|
}
|
141
97
|
|
142
98
|
private void update(List<RecordForUpdate> records) {
|
143
|
-
executeWithRetry(() -> client.record().updateRecords(task.getAppId(), records));
|
99
|
+
executeWithRetry(() -> client.get().record().updateRecords(task.getAppId(), records));
|
144
100
|
}
|
145
101
|
|
146
102
|
private <T> T executeWithRetry(Supplier<T> operation) {
|
147
|
-
connectIfNeeded();
|
148
103
|
KintoneRetryOption retryOption = task.getRetryOptions();
|
149
104
|
try {
|
150
105
|
return retryExecutor()
|
@@ -154,7 +109,7 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
154
109
|
.runInterruptible(
|
155
110
|
new Retryable<T>() {
|
156
111
|
@Override
|
157
|
-
public T call()
|
112
|
+
public T call() {
|
158
113
|
return operation.get();
|
159
114
|
}
|
160
115
|
|
@@ -176,8 +131,7 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
176
131
|
|
177
132
|
@Override
|
178
133
|
public void onRetry(
|
179
|
-
Exception exception, int retryCount, int retryLimit, int retryWait)
|
180
|
-
throws RetryGiveupException {
|
134
|
+
Exception exception, int retryCount, int retryLimit, int retryWait) {
|
181
135
|
String message =
|
182
136
|
String.format(
|
183
137
|
"Retrying %d/%d after %d seconds. Message: %s",
|
@@ -190,27 +144,31 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
190
144
|
}
|
191
145
|
|
192
146
|
@Override
|
193
|
-
public void onGiveup(Exception firstException, Exception lastException)
|
194
|
-
throws RetryGiveupException {}
|
147
|
+
public void onGiveup(Exception firstException, Exception lastException) {}
|
195
148
|
});
|
196
149
|
} catch (RetryGiveupException | InterruptedException e) {
|
197
150
|
throw new RuntimeException("kintone throw exception", e);
|
198
151
|
}
|
199
152
|
}
|
200
153
|
|
201
|
-
|
154
|
+
public void insertPage(Page page) {
|
202
155
|
List<Record> records = new ArrayList<>();
|
203
156
|
reader.setPage(page);
|
204
157
|
KintoneColumnVisitor visitor =
|
205
158
|
new KintoneColumnVisitor(
|
206
|
-
reader,
|
159
|
+
reader,
|
160
|
+
task.getDerivedColumns(),
|
161
|
+
task.getColumnOptions(),
|
162
|
+
task.getPreferNulls(),
|
163
|
+
task.getIgnoreNulls(),
|
164
|
+
task.getReduceKeyName().orElse(null));
|
207
165
|
while (reader.nextRecord()) {
|
208
166
|
Record record = new Record();
|
209
167
|
visitor.setRecord(record);
|
210
168
|
reader.getSchema().visitColumns(visitor);
|
211
169
|
putWrongTypeFields(record);
|
212
170
|
records.add(record);
|
213
|
-
if (records.size() ==
|
171
|
+
if (records.size() == task.getChunkSize()) {
|
214
172
|
insert(records);
|
215
173
|
records.clear();
|
216
174
|
}
|
@@ -220,30 +178,34 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
220
178
|
}
|
221
179
|
}
|
222
180
|
|
223
|
-
|
181
|
+
public void updatePage(Page page) {
|
182
|
+
Skip skip = task.getSkipIfNonExistingIdOrUpdateKey();
|
224
183
|
List<RecordForUpdate> records = new ArrayList<>();
|
225
184
|
reader.setPage(page);
|
226
185
|
KintoneColumnVisitor visitor =
|
227
186
|
new KintoneColumnVisitor(
|
228
187
|
reader,
|
188
|
+
task.getDerivedColumns(),
|
229
189
|
task.getColumnOptions(),
|
230
190
|
task.getPreferNulls(),
|
231
191
|
task.getIgnoreNulls(),
|
232
|
-
task.
|
233
|
-
|
192
|
+
task.getReduceKeyName().orElse(null),
|
193
|
+
task.getUpdateKeyName().orElse(Id.FIELD));
|
234
194
|
while (reader.nextRecord()) {
|
235
195
|
Record record = new Record();
|
236
|
-
|
196
|
+
IdOrUpdateKey idOrUpdateKey = new IdOrUpdateKey();
|
237
197
|
visitor.setRecord(record);
|
238
|
-
visitor.
|
198
|
+
visitor.setIdOrUpdateKey(idOrUpdateKey);
|
239
199
|
reader.getSchema().visitColumns(visitor);
|
240
200
|
putWrongTypeFields(record);
|
241
|
-
if (
|
242
|
-
|
201
|
+
if (skip == Skip.NEVER && !idOrUpdateKey.isPresent()) {
|
202
|
+
throw new RuntimeException("No id or update key value was specified");
|
203
|
+
} else if (!idOrUpdateKey.isPresent()) {
|
204
|
+
LOGGER.warn("Record skipped because no id or update key value was specified");
|
243
205
|
continue;
|
244
206
|
}
|
245
|
-
records.add(
|
246
|
-
if (records.size() ==
|
207
|
+
records.add(idOrUpdateKey.forUpdate(record));
|
208
|
+
if (records.size() == task.getChunkSize()) {
|
247
209
|
update(records);
|
248
210
|
records.clear();
|
249
211
|
}
|
@@ -253,57 +215,91 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
253
215
|
}
|
254
216
|
}
|
255
217
|
|
256
|
-
|
218
|
+
public void upsertPage(Page page) {
|
257
219
|
List<Record> records = new ArrayList<>();
|
258
|
-
List<
|
220
|
+
List<IdOrUpdateKey> idOrUpdateKeys = new ArrayList<>();
|
259
221
|
reader.setPage(page);
|
260
222
|
KintoneColumnVisitor visitor =
|
261
223
|
new KintoneColumnVisitor(
|
262
224
|
reader,
|
225
|
+
task.getDerivedColumns(),
|
263
226
|
task.getColumnOptions(),
|
264
227
|
task.getPreferNulls(),
|
265
228
|
task.getIgnoreNulls(),
|
266
|
-
task.
|
267
|
-
|
229
|
+
task.getReduceKeyName().orElse(null),
|
230
|
+
task.getUpdateKeyName().orElse(Id.FIELD));
|
268
231
|
while (reader.nextRecord()) {
|
269
232
|
Record record = new Record();
|
270
|
-
|
233
|
+
IdOrUpdateKey idOrUpdateKey = new IdOrUpdateKey();
|
271
234
|
visitor.setRecord(record);
|
272
|
-
visitor.
|
235
|
+
visitor.setIdOrUpdateKey(idOrUpdateKey);
|
273
236
|
reader.getSchema().visitColumns(visitor);
|
274
237
|
putWrongTypeFields(record);
|
275
238
|
records.add(record);
|
276
|
-
|
239
|
+
idOrUpdateKeys.add(idOrUpdateKey);
|
277
240
|
if (records.size() == UPSERT_BATCH_SIZE) {
|
278
|
-
upsert(records,
|
241
|
+
upsert(records, idOrUpdateKeys);
|
279
242
|
records.clear();
|
280
|
-
|
243
|
+
idOrUpdateKeys.clear();
|
281
244
|
}
|
282
245
|
}
|
283
246
|
if (!records.isEmpty()) {
|
284
|
-
upsert(records,
|
247
|
+
upsert(records, idOrUpdateKeys);
|
285
248
|
}
|
286
249
|
}
|
287
250
|
|
288
|
-
private void upsert(List<Record> records, List<
|
289
|
-
if (records.size() !=
|
290
|
-
throw new RuntimeException("records.size() !=
|
251
|
+
private void upsert(List<Record> records, List<IdOrUpdateKey> idOrUpdateKeys) {
|
252
|
+
if (records.size() != idOrUpdateKeys.size()) {
|
253
|
+
throw new RuntimeException("records.size() != idOrUpdateKeys.size()");
|
291
254
|
}
|
292
|
-
|
255
|
+
Skip skip = task.getSkipIfNonExistingIdOrUpdateKey();
|
256
|
+
String columnName = task.getUpdateKeyName().orElse(Id.FIELD);
|
257
|
+
boolean isId = columnName.equals(Id.FIELD);
|
258
|
+
List<String> existingValues =
|
259
|
+
executeWithRetry(() -> getExistingValuesByIdOrUpdateKey(idOrUpdateKeys, columnName));
|
293
260
|
List<Record> insertRecords = new ArrayList<>();
|
294
261
|
List<RecordForUpdate> updateRecords = new ArrayList<>();
|
295
262
|
for (int i = 0; i < records.size(); i++) {
|
263
|
+
RecordForUpdate recordForUpdate = null;
|
296
264
|
Record record = records.get(i);
|
297
|
-
|
298
|
-
if (existsRecord(existingValues,
|
299
|
-
|
265
|
+
IdOrUpdateKey idOrUpdateKey = idOrUpdateKeys.get(i);
|
266
|
+
if (existsRecord(existingValues, idOrUpdateKey)) {
|
267
|
+
recordForUpdate = idOrUpdateKey.forUpdate(record);
|
268
|
+
} else if (skip == Skip.ALWAYS && idOrUpdateKey.isPresent()) {
|
269
|
+
LOGGER.warn(
|
270
|
+
"Record skipped because non existing id or update key '"
|
271
|
+
+ idOrUpdateKey.getValue()
|
272
|
+
+ "' was specified");
|
273
|
+
continue;
|
274
|
+
} else if (skip == Skip.ALWAYS && !idOrUpdateKey.isPresent()) {
|
275
|
+
LOGGER.warn("Record skipped because no id or update key value was specified");
|
276
|
+
continue;
|
277
|
+
} else if (skip == Skip.AUTO && idOrUpdateKey.isIdPresent()) {
|
278
|
+
LOGGER.warn(
|
279
|
+
"Record skipped because non existing id '"
|
280
|
+
+ idOrUpdateKey.getValue()
|
281
|
+
+ "' was specified");
|
282
|
+
continue;
|
283
|
+
} else if (skip == Skip.AUTO && !isId && !idOrUpdateKey.isUpdateKeyPresent()) {
|
284
|
+
LOGGER.warn("Record skipped because no update key value was specified");
|
285
|
+
continue;
|
286
|
+
} else if (idOrUpdateKey.isIdPresent()) {
|
287
|
+
LOGGER.warn(
|
288
|
+
"Record inserted though non existing id '"
|
289
|
+
+ idOrUpdateKey.getValue()
|
290
|
+
+ "' was specified");
|
291
|
+
} else if (!isId && !idOrUpdateKey.isUpdateKeyPresent()) {
|
292
|
+
LOGGER.warn("Record inserted though no update key value was specified");
|
293
|
+
}
|
294
|
+
if (recordForUpdate != null) {
|
295
|
+
updateRecords.add(recordForUpdate);
|
300
296
|
} else {
|
301
297
|
insertRecords.add(record);
|
302
298
|
}
|
303
|
-
if (insertRecords.size() ==
|
299
|
+
if (insertRecords.size() == task.getChunkSize()) {
|
304
300
|
insert(insertRecords);
|
305
301
|
insertRecords.clear();
|
306
|
-
} else if (updateRecords.size() ==
|
302
|
+
} else if (updateRecords.size() == task.getChunkSize()) {
|
307
303
|
update(updateRecords);
|
308
304
|
updateRecords.clear();
|
309
305
|
}
|
@@ -316,60 +312,57 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
316
312
|
}
|
317
313
|
}
|
318
314
|
|
319
|
-
private List<String>
|
320
|
-
|
321
|
-
updateKeys.stream()
|
322
|
-
.map(UpdateKey::getField)
|
323
|
-
.filter(Objects::nonNull)
|
324
|
-
.findFirst()
|
325
|
-
.orElse(null);
|
326
|
-
if (fieldCode == null) {
|
327
|
-
return Collections.emptyList();
|
328
|
-
}
|
329
|
-
Function<Record, String> fieldValueAsString;
|
330
|
-
FieldType fieldType = getFieldType(fieldCode);
|
331
|
-
if (fieldType == FieldType.SINGLE_LINE_TEXT) {
|
332
|
-
fieldValueAsString = record -> record.getSingleLineTextFieldValue(fieldCode);
|
333
|
-
} else if (fieldType == FieldType.NUMBER) {
|
334
|
-
fieldValueAsString = record -> toString(record.getNumberFieldValue(fieldCode));
|
335
|
-
} else {
|
336
|
-
throw new ConfigException("The update_key must be 'SINGLE_LINE_TEXT' or 'NUMBER'.");
|
337
|
-
}
|
315
|
+
private List<String> getExistingValuesByIdOrUpdateKey(
|
316
|
+
List<IdOrUpdateKey> idOrUpdateKeys, String columnName) {
|
338
317
|
List<String> queryValues =
|
339
|
-
|
340
|
-
.filter(
|
318
|
+
idOrUpdateKeys.stream()
|
319
|
+
.filter(IdOrUpdateKey::isPresent)
|
341
320
|
.map(k -> "\"" + k.getValue() + "\"")
|
342
321
|
.collect(Collectors.toList());
|
343
322
|
if (queryValues.isEmpty()) {
|
344
323
|
return Collections.emptyList();
|
345
324
|
}
|
325
|
+
return columnName.equals(Id.FIELD)
|
326
|
+
? getExistingValuesById(queryValues)
|
327
|
+
: getExistingValuesByUpdateKey(columnName, queryValues);
|
328
|
+
}
|
329
|
+
|
330
|
+
private List<String> getExistingValuesById(List<String> queryValues) {
|
331
|
+
return getExistingValues(Id.FIELD, Record::getId, queryValues);
|
332
|
+
}
|
333
|
+
|
334
|
+
private List<String> getExistingValuesByUpdateKey(String columnName, List<String> queryValues) {
|
335
|
+
KintoneColumnOption option = task.getColumnOptions().get(columnName);
|
336
|
+
String fieldCode = option != null ? option.getFieldCode() : columnName;
|
337
|
+
KintoneColumnType type = KintoneColumnType.valueOf(getFieldType(fieldCode).name());
|
338
|
+
return getExistingValues(fieldCode, record -> type.getValue(record, fieldCode), queryValues);
|
339
|
+
}
|
340
|
+
|
341
|
+
private List<String> getExistingValues(
|
342
|
+
String fieldCode, Function<Record, Object> toValue, List<String> queryValues) {
|
346
343
|
String cursorId =
|
347
344
|
client
|
345
|
+
.get()
|
348
346
|
.record()
|
349
347
|
.createCursor(
|
350
348
|
task.getAppId(),
|
351
349
|
Collections.singletonList(fieldCode),
|
352
350
|
fieldCode + " in (" + String.join(",", queryValues) + ")");
|
353
|
-
List<Record>
|
351
|
+
List<Record> records = new ArrayList<>();
|
354
352
|
while (true) {
|
355
|
-
GetRecordsByCursorResponseBody
|
356
|
-
|
357
|
-
|
358
|
-
if (!resp.hasNext()) {
|
353
|
+
GetRecordsByCursorResponseBody cursor = client.get().record().getRecordsByCursor(cursorId);
|
354
|
+
records.addAll(cursor.getRecords());
|
355
|
+
if (!cursor.hasNext()) {
|
359
356
|
break;
|
360
357
|
}
|
361
358
|
}
|
362
|
-
return
|
363
|
-
.map(
|
359
|
+
return records.stream()
|
360
|
+
.map(toValue)
|
361
|
+
.map(KintonePageOutput::toString)
|
364
362
|
.filter(Objects::nonNull)
|
365
363
|
.collect(Collectors.toList());
|
366
364
|
}
|
367
365
|
|
368
|
-
private boolean existsRecord(List<String> existingValues, UpdateKey updateKey) {
|
369
|
-
String value = toString(updateKey.getValue());
|
370
|
-
return value != null && existingValues.stream().anyMatch(v -> v.equals(value));
|
371
|
-
}
|
372
|
-
|
373
366
|
private void putWrongTypeFields(Record record) {
|
374
367
|
record.getFieldCodes(true).stream()
|
375
368
|
.map(
|
@@ -381,9 +374,12 @@ public class KintonePageOutput implements TransactionalPageOutput {
|
|
381
374
|
}
|
382
375
|
|
383
376
|
private FieldType getFieldType(String fieldCode) {
|
384
|
-
|
385
|
-
|
386
|
-
|
377
|
+
return client.get().getFieldType(fieldCode);
|
378
|
+
}
|
379
|
+
|
380
|
+
private static boolean existsRecord(List<String> existingValues, IdOrUpdateKey idOrUpdateKey) {
|
381
|
+
String value = toString(idOrUpdateKey.getValue());
|
382
|
+
return value != null && existingValues.stream().anyMatch(v -> v.equals(value));
|
387
383
|
}
|
388
384
|
|
389
385
|
private static String toString(Object value) {
|
@@ -0,0 +1,33 @@
|
|
1
|
+
package org.embulk.output.kintone;
|
2
|
+
|
3
|
+
import com.fasterxml.jackson.annotation.JsonCreator;
|
4
|
+
import com.fasterxml.jackson.annotation.JsonProperty;
|
5
|
+
|
6
|
+
public class KintoneSortColumn {
|
7
|
+
private final String name;
|
8
|
+
private final Order order;
|
9
|
+
|
10
|
+
@JsonCreator
|
11
|
+
public KintoneSortColumn(@JsonProperty("name") String name, @JsonProperty("order") Order order) {
|
12
|
+
this.name = name;
|
13
|
+
this.order = order;
|
14
|
+
}
|
15
|
+
|
16
|
+
public String getName() {
|
17
|
+
return name;
|
18
|
+
}
|
19
|
+
|
20
|
+
public Order getOrder() {
|
21
|
+
return order;
|
22
|
+
}
|
23
|
+
|
24
|
+
public enum Order {
|
25
|
+
ASC,
|
26
|
+
DESC;
|
27
|
+
|
28
|
+
@JsonCreator
|
29
|
+
public static Order of(String name) {
|
30
|
+
return valueOf(name.toUpperCase());
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
@@ -1,10 +1,14 @@
|
|
1
1
|
package org.embulk.output.kintone;
|
2
2
|
|
3
|
+
import java.util.List;
|
3
4
|
import java.util.Map;
|
4
5
|
import java.util.Optional;
|
6
|
+
import java.util.Set;
|
5
7
|
import org.embulk.config.Config;
|
6
8
|
import org.embulk.config.ConfigDefault;
|
7
9
|
import org.embulk.config.Task;
|
10
|
+
import org.embulk.output.kintone.record.Skip;
|
11
|
+
import org.embulk.spi.Column;
|
8
12
|
|
9
13
|
public interface PluginTask extends Task {
|
10
14
|
@Config("domain")
|
@@ -49,6 +53,10 @@ public interface PluginTask extends Task {
|
|
49
53
|
@ConfigDefault("\"false\"")
|
50
54
|
boolean getIgnoreNulls();
|
51
55
|
|
56
|
+
@Config("skip_if_non_existing_id_or_update_key")
|
57
|
+
@ConfigDefault("\"auto\"")
|
58
|
+
Skip getSkipIfNonExistingIdOrUpdateKey();
|
59
|
+
|
52
60
|
@Config("mode")
|
53
61
|
@ConfigDefault("\"insert\"")
|
54
62
|
String getMode();
|
@@ -57,7 +65,31 @@ public interface PluginTask extends Task {
|
|
57
65
|
@ConfigDefault("null")
|
58
66
|
Optional<String> getUpdateKeyName();
|
59
67
|
|
68
|
+
@Config("reduce_key")
|
69
|
+
@ConfigDefault("null")
|
70
|
+
Optional<String> getReduceKeyName();
|
71
|
+
|
72
|
+
@Config("sort_columns")
|
73
|
+
@ConfigDefault("[]")
|
74
|
+
List<KintoneSortColumn> getSortColumns();
|
75
|
+
|
76
|
+
@Config("max_sort_tmp_files")
|
77
|
+
@ConfigDefault("null")
|
78
|
+
Optional<Integer> getMaxSortTmpFiles();
|
79
|
+
|
80
|
+
@Config("max_sort_memory")
|
81
|
+
@ConfigDefault("null")
|
82
|
+
Optional<Long> getMaxSortMemory();
|
83
|
+
|
84
|
+
@Config("chunk_size")
|
85
|
+
@ConfigDefault("100")
|
86
|
+
Integer getChunkSize();
|
87
|
+
|
60
88
|
@Config("retry_options")
|
61
89
|
@ConfigDefault("{}")
|
62
90
|
KintoneRetryOption getRetryOptions();
|
91
|
+
|
92
|
+
Set<Column> getDerivedColumns();
|
93
|
+
|
94
|
+
void setDerivedColumns(Set<Column> columns);
|
63
95
|
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package org.embulk.output.kintone.deserializer;
|
2
|
+
|
3
|
+
import com.fasterxml.jackson.core.JsonParser;
|
4
|
+
import com.fasterxml.jackson.databind.DeserializationContext;
|
5
|
+
import com.fasterxml.jackson.databind.JsonDeserializer;
|
6
|
+
import java.util.function.BiFunction;
|
7
|
+
|
8
|
+
public class DeserializeApplier<T> extends JsonDeserializer<T> {
|
9
|
+
private final BiFunction<JsonParser, DeserializationContext, T> deserializer;
|
10
|
+
|
11
|
+
public DeserializeApplier(BiFunction<JsonParser, DeserializationContext, T> deserializer) {
|
12
|
+
this.deserializer = deserializer;
|
13
|
+
}
|
14
|
+
|
15
|
+
@Override
|
16
|
+
public T deserialize(JsonParser parser, DeserializationContext context) {
|
17
|
+
return deserializer.apply(parser, context);
|
18
|
+
}
|
19
|
+
}
|