embulk-input-kintone 0.1.1 → 0.1.2
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/.travis.yml +7 -0
- data/README.md +3 -1
- data/build.gradle +3 -1
- data/gradlew.bat +84 -84
- data/src/main/java/org/embulk/input/kintone/KintoneClient.java +24 -19
- data/src/main/java/org/embulk/input/kintone/KintoneInputColumnVisitor.java +1 -1
- data/src/main/java/org/embulk/input/kintone/KintoneInputPlugin.java +18 -3
- data/src/test/java/org/embulk/input/kintone/TestHelper.java +17 -0
- data/src/test/java/org/embulk/input/kintone/TestKintoneAccessor.java +15 -24
- data/src/test/java/org/embulk/input/kintone/TestKintoneClient.java +15 -10
- data/src/test/java/org/embulk/input/kintone/TestKintoneInputPlugin.java +110 -1
- data/src/test/resources/org/embulk/input/kintone/base.yml +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7228024b39d9a99ed12bb46ed0533fbf0e8bc203
|
4
|
+
data.tar.gz: 79da56d30429a42c0f286c6e898f9f67b8ee17c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8dd98237c2e4d4141466ff8f1405eb3c36e4b6f531f0fa3571abc17336a72c8f04cbcc8eecfa305d0c25470c4ae15cdb142d259d74c6c6867c82b3b81f69050d
|
7
|
+
data.tar.gz: ba3f6ca0f421e40119a68f4b076085d2b405e4663a2a733ad49bc7147fac4be05e835ad48bcc853088767f565576f712b6092a800b68f4f64963b9e43e036367
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Kintone input plugin for Embulk
|
2
|
+
[](https://travis-ci.org/trocco-io/embulk-input-kintone)
|
2
3
|
|
3
4
|
## Overview
|
4
5
|
Kintone input plugin for Embulk loads app records from Kintone.
|
@@ -13,7 +14,6 @@ embulk 0.9 is only supported due to the dependency of kintone-java-sdk 0.4.0, wh
|
|
13
14
|
- [ ] Guess
|
14
15
|
- [ ] Subtable data type support
|
15
16
|
- [ ] field name mapping
|
16
|
-
- [ ] timestamp_format in fields
|
17
17
|
- [ ] handle certification fot authentication
|
18
18
|
|
19
19
|
## Configuration
|
@@ -30,6 +30,7 @@ embulk 0.9 is only supported due to the dependency of kintone-java-sdk 0.4.0, wh
|
|
30
30
|
- **fields** (required)
|
31
31
|
- **name** the field code of Kintone app record will be retrieved.
|
32
32
|
- **type** Column values are converted to this embulk type. Available values options are: boolean, long, double, string, json, timestamp)
|
33
|
+
- **format** Format of the timestamp if type is timestamp. The format for kintone DATETIME is `%Y-%m-%dT%H:%M:%S%z`.
|
33
34
|
|
34
35
|
Kintone API has the limitation, therefore this plugin also faces it. See [official documentation](https://developer.kintone.io/hc/en-us/articles/212495188/)
|
35
36
|
|
@@ -66,6 +67,7 @@ in:
|
|
66
67
|
- {name: Time, type: string}
|
67
68
|
- {name: Created_datatime, type: string}
|
68
69
|
- {name: foo, type: string}
|
70
|
+
- {name: datetime, type: timestamp, format: '%Y-%m-%dT%H:%M:%S%z'}
|
69
71
|
```
|
70
72
|
|
71
73
|
## Build
|
data/build.gradle
CHANGED
@@ -13,7 +13,7 @@ configurations {
|
|
13
13
|
provided
|
14
14
|
}
|
15
15
|
|
16
|
-
version = "0.1.
|
16
|
+
version = "0.1.2"
|
17
17
|
|
18
18
|
sourceCompatibility = 1.8
|
19
19
|
targetCompatibility = 1.8
|
@@ -26,6 +26,8 @@ dependencies {
|
|
26
26
|
testCompile "junit:junit:4.+"
|
27
27
|
testCompile 'org.embulk:embulk-standards:0.9.12'
|
28
28
|
testCompile 'org.embulk:embulk-test:0.9.12'
|
29
|
+
testCompile "org.mockito:mockito-core:1.+"
|
30
|
+
testCompile "org.embulk:embulk-core:0.9.12:tests"
|
29
31
|
}
|
30
32
|
|
31
33
|
task classpath(type: Copy, dependsOn: ["jar"]) {
|
data/gradlew.bat
CHANGED
@@ -1,84 +1,84 @@
|
|
1
|
-
@if "%DEBUG%" == "" @echo off
|
2
|
-
@rem ##########################################################################
|
3
|
-
@rem
|
4
|
-
@rem Gradle startup script for Windows
|
5
|
-
@rem
|
6
|
-
@rem ##########################################################################
|
7
|
-
|
8
|
-
@rem Set local scope for the variables with windows NT shell
|
9
|
-
if "%OS%"=="Windows_NT" setlocal
|
10
|
-
|
11
|
-
set DIRNAME=%~dp0
|
12
|
-
if "%DIRNAME%" == "" set DIRNAME=.
|
13
|
-
set APP_BASE_NAME=%~n0
|
14
|
-
set APP_HOME=%DIRNAME%
|
15
|
-
|
16
|
-
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
17
|
-
set DEFAULT_JVM_OPTS=
|
18
|
-
|
19
|
-
@rem Find java.exe
|
20
|
-
if defined JAVA_HOME goto findJavaFromJavaHome
|
21
|
-
|
22
|
-
set JAVA_EXE=java.exe
|
23
|
-
%JAVA_EXE% -version >NUL 2>&1
|
24
|
-
if "%ERRORLEVEL%" == "0" goto init
|
25
|
-
|
26
|
-
echo.
|
27
|
-
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
28
|
-
echo.
|
29
|
-
echo Please set the JAVA_HOME variable in your environment to match the
|
30
|
-
echo location of your Java installation.
|
31
|
-
|
32
|
-
goto fail
|
33
|
-
|
34
|
-
:findJavaFromJavaHome
|
35
|
-
set JAVA_HOME=%JAVA_HOME:"=%
|
36
|
-
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
37
|
-
|
38
|
-
if exist "%JAVA_EXE%" goto init
|
39
|
-
|
40
|
-
echo.
|
41
|
-
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
42
|
-
echo.
|
43
|
-
echo Please set the JAVA_HOME variable in your environment to match the
|
44
|
-
echo location of your Java installation.
|
45
|
-
|
46
|
-
goto fail
|
47
|
-
|
48
|
-
:init
|
49
|
-
@rem Get command-line arguments, handling Windows variants
|
50
|
-
|
51
|
-
if not "%OS%" == "Windows_NT" goto win9xME_args
|
52
|
-
|
53
|
-
:win9xME_args
|
54
|
-
@rem Slurp the command line arguments.
|
55
|
-
set CMD_LINE_ARGS=
|
56
|
-
set _SKIP=2
|
57
|
-
|
58
|
-
:win9xME_args_slurp
|
59
|
-
if "x%~1" == "x" goto execute
|
60
|
-
|
61
|
-
set CMD_LINE_ARGS=%*
|
62
|
-
|
63
|
-
:execute
|
64
|
-
@rem Setup the command line
|
65
|
-
|
66
|
-
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
67
|
-
|
68
|
-
@rem Execute Gradle
|
69
|
-
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
70
|
-
|
71
|
-
:end
|
72
|
-
@rem End local scope for the variables with windows NT shell
|
73
|
-
if "%ERRORLEVEL%"=="0" goto mainEnd
|
74
|
-
|
75
|
-
:fail
|
76
|
-
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
77
|
-
rem the _cmd.exe /c_ return code!
|
78
|
-
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
79
|
-
exit /b 1
|
80
|
-
|
81
|
-
:mainEnd
|
82
|
-
if "%OS%"=="Windows_NT" endlocal
|
83
|
-
|
84
|
-
:omega
|
1
|
+
@if "%DEBUG%" == "" @echo off
|
2
|
+
@rem ##########################################################################
|
3
|
+
@rem
|
4
|
+
@rem Gradle startup script for Windows
|
5
|
+
@rem
|
6
|
+
@rem ##########################################################################
|
7
|
+
|
8
|
+
@rem Set local scope for the variables with windows NT shell
|
9
|
+
if "%OS%"=="Windows_NT" setlocal
|
10
|
+
|
11
|
+
set DIRNAME=%~dp0
|
12
|
+
if "%DIRNAME%" == "" set DIRNAME=.
|
13
|
+
set APP_BASE_NAME=%~n0
|
14
|
+
set APP_HOME=%DIRNAME%
|
15
|
+
|
16
|
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
17
|
+
set DEFAULT_JVM_OPTS=
|
18
|
+
|
19
|
+
@rem Find java.exe
|
20
|
+
if defined JAVA_HOME goto findJavaFromJavaHome
|
21
|
+
|
22
|
+
set JAVA_EXE=java.exe
|
23
|
+
%JAVA_EXE% -version >NUL 2>&1
|
24
|
+
if "%ERRORLEVEL%" == "0" goto init
|
25
|
+
|
26
|
+
echo.
|
27
|
+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
28
|
+
echo.
|
29
|
+
echo Please set the JAVA_HOME variable in your environment to match the
|
30
|
+
echo location of your Java installation.
|
31
|
+
|
32
|
+
goto fail
|
33
|
+
|
34
|
+
:findJavaFromJavaHome
|
35
|
+
set JAVA_HOME=%JAVA_HOME:"=%
|
36
|
+
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
37
|
+
|
38
|
+
if exist "%JAVA_EXE%" goto init
|
39
|
+
|
40
|
+
echo.
|
41
|
+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
42
|
+
echo.
|
43
|
+
echo Please set the JAVA_HOME variable in your environment to match the
|
44
|
+
echo location of your Java installation.
|
45
|
+
|
46
|
+
goto fail
|
47
|
+
|
48
|
+
:init
|
49
|
+
@rem Get command-line arguments, handling Windows variants
|
50
|
+
|
51
|
+
if not "%OS%" == "Windows_NT" goto win9xME_args
|
52
|
+
|
53
|
+
:win9xME_args
|
54
|
+
@rem Slurp the command line arguments.
|
55
|
+
set CMD_LINE_ARGS=
|
56
|
+
set _SKIP=2
|
57
|
+
|
58
|
+
:win9xME_args_slurp
|
59
|
+
if "x%~1" == "x" goto execute
|
60
|
+
|
61
|
+
set CMD_LINE_ARGS=%*
|
62
|
+
|
63
|
+
:execute
|
64
|
+
@rem Setup the command line
|
65
|
+
|
66
|
+
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
67
|
+
|
68
|
+
@rem Execute Gradle
|
69
|
+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
70
|
+
|
71
|
+
:end
|
72
|
+
@rem End local scope for the variables with windows NT shell
|
73
|
+
if "%ERRORLEVEL%"=="0" goto mainEnd
|
74
|
+
|
75
|
+
:fail
|
76
|
+
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
77
|
+
rem the _cmd.exe /c_ return code!
|
78
|
+
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
79
|
+
exit /b 1
|
80
|
+
|
81
|
+
:mainEnd
|
82
|
+
if "%OS%"=="Windows_NT" endlocal
|
83
|
+
|
84
|
+
:omega
|
@@ -14,49 +14,54 @@ import java.util.ArrayList;
|
|
14
14
|
|
15
15
|
public class KintoneClient {
|
16
16
|
private final Logger logger = LoggerFactory.getLogger(KintoneClient.class);
|
17
|
-
private final PluginTask task;
|
18
|
-
private ArrayList<String> fields;
|
19
17
|
private Auth kintoneAuth;
|
20
18
|
private Record kintoneRecordManager;
|
21
19
|
private Connection con;
|
22
20
|
|
23
|
-
public KintoneClient(
|
24
|
-
this.task = task;
|
21
|
+
public KintoneClient(){
|
25
22
|
this.kintoneAuth = new Auth();
|
23
|
+
}
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
this.setAuth();
|
33
|
-
if (task.getGuestSpaceId().isPresent()) {
|
34
|
-
this.con = new Connection(task.getDomain(), this.kintoneAuth, task.getGuestSpaceId().or(-1));
|
25
|
+
public void validateAuth(final PluginTask task) throws ConfigException{
|
26
|
+
if (task.getUsername().isPresent() && task.getPassword().isPresent()) {
|
27
|
+
return;
|
28
|
+
} else if (task.getToken().isPresent()) {
|
29
|
+
return;
|
35
30
|
} else {
|
36
|
-
|
31
|
+
throw new ConfigException("Username and password or token must be provided");
|
37
32
|
}
|
38
|
-
this.kintoneRecordManager = new Record(con);
|
39
33
|
}
|
40
34
|
|
41
|
-
|
35
|
+
public void connect(final PluginTask task) {
|
42
36
|
if (task.getUsername().isPresent() && task.getPassword().isPresent()) {
|
43
37
|
this.kintoneAuth.setPasswordAuth(task.getUsername().get(), task.getPassword().get());
|
44
38
|
} else if (task.getToken().isPresent()) {
|
45
39
|
this.kintoneAuth.setApiToken(task.getToken().get());
|
46
|
-
} else {
|
47
|
-
throw new ConfigException("Username and password or token must be provided");
|
48
40
|
}
|
49
41
|
|
50
42
|
if (task.getBasicAuthUsername().isPresent() && task.getBasicAuthPassword().isPresent()) {
|
51
43
|
this.kintoneAuth.setBasicAuth(task.getBasicAuthUsername().get(),
|
52
44
|
task.getBasicAuthPassword().get());
|
53
45
|
}
|
46
|
+
|
47
|
+
if (task.getGuestSpaceId().isPresent()) {
|
48
|
+
this.con = new Connection(task.getDomain(), this.kintoneAuth, task.getGuestSpaceId().or(-1));
|
49
|
+
} else {
|
50
|
+
this.con = new Connection(task.getDomain(), this.kintoneAuth);
|
51
|
+
}
|
52
|
+
this.kintoneRecordManager = new Record(con);
|
54
53
|
}
|
55
54
|
|
56
|
-
|
55
|
+
|
56
|
+
public GetRecordsResponse getResponse(final PluginTask task) {
|
57
|
+
ArrayList<String> fields = new ArrayList<>();
|
58
|
+
for (ColumnConfig c : task.getFields().getColumns()
|
59
|
+
) {
|
60
|
+
fields.add(c.getName());
|
61
|
+
}
|
57
62
|
try {
|
58
63
|
return kintoneRecordManager.getAllRecordsByQuery(
|
59
|
-
|
64
|
+
task.getAppId(), task.getQuery().or(""), fields);
|
60
65
|
} catch (Exception e) {
|
61
66
|
throw new RuntimeException(e);
|
62
67
|
}
|
@@ -16,7 +16,7 @@ import org.slf4j.LoggerFactory;
|
|
16
16
|
import com.google.gson.JsonElement;
|
17
17
|
|
18
18
|
public class KintoneInputColumnVisitor implements ColumnVisitor {
|
19
|
-
private static final String DEFAULT_TIMESTAMP_PATTERN = "%Y-%m-%dT%H:%M:%S
|
19
|
+
private static final String DEFAULT_TIMESTAMP_PATTERN = "%Y-%m-%dT%H:%M:%S%z";
|
20
20
|
private final Logger logger = LoggerFactory.getLogger(KintoneInputColumnVisitor.class);
|
21
21
|
|
22
22
|
private final PageBuilder pageBuilder;
|
@@ -3,6 +3,7 @@ package org.embulk.input.kintone;
|
|
3
3
|
import java.util.HashMap;
|
4
4
|
import java.util.List;
|
5
5
|
|
6
|
+
import com.google.common.annotations.VisibleForTesting;
|
6
7
|
import org.embulk.config.*;
|
7
8
|
import org.embulk.spi.Exec;
|
8
9
|
import org.embulk.spi.PageBuilder;
|
@@ -51,9 +52,11 @@ public class KintoneInputPlugin
|
|
51
52
|
PluginTask task = taskSource.loadTask(PluginTask.class);
|
52
53
|
|
53
54
|
try {
|
54
|
-
try (PageBuilder pageBuilder =
|
55
|
-
KintoneClient client =
|
56
|
-
|
55
|
+
try (PageBuilder pageBuilder = getPageBuilder(schema, output)) {
|
56
|
+
KintoneClient client = getKintoneClient();
|
57
|
+
client.validateAuth(task);
|
58
|
+
client.connect(task);
|
59
|
+
GetRecordsResponse response = client.getResponse(task);
|
57
60
|
for (HashMap<String, FieldValue> record : response.getRecords()) {
|
58
61
|
schema.visitColumns(new KintoneInputColumnVisitor(new KintoneAccessor(record), pageBuilder, task));
|
59
62
|
pageBuilder.addRecord();
|
@@ -71,4 +74,16 @@ public class KintoneInputPlugin
|
|
71
74
|
public ConfigDiff guess(ConfigSource config) {
|
72
75
|
return Exec.newConfigDiff();
|
73
76
|
}
|
77
|
+
|
78
|
+
@VisibleForTesting
|
79
|
+
protected PageBuilder getPageBuilder(final Schema schema, final PageOutput output)
|
80
|
+
{
|
81
|
+
return new PageBuilder(Exec.getBufferAllocator(), schema, output);
|
82
|
+
}
|
83
|
+
|
84
|
+
@VisibleForTesting
|
85
|
+
protected KintoneClient getKintoneClient(){
|
86
|
+
return new KintoneClient();
|
87
|
+
}
|
88
|
+
|
74
89
|
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
package org.embulk.input.kintone;
|
2
|
+
|
3
|
+
import com.cybozu.kintone.client.model.app.form.FieldType;
|
4
|
+
import com.cybozu.kintone.client.model.record.field.FieldValue;
|
5
|
+
|
6
|
+
import java.util.HashMap;
|
7
|
+
|
8
|
+
public class TestHelper {
|
9
|
+
public static HashMap<String, FieldValue> addField(HashMap<String, FieldValue> record, String code, FieldType type,
|
10
|
+
Object value) {
|
11
|
+
FieldValue newField = new FieldValue();
|
12
|
+
newField.setType(type);
|
13
|
+
newField.setValue(value);
|
14
|
+
record.put(code, newField);
|
15
|
+
return record;
|
16
|
+
}
|
17
|
+
}
|
@@ -24,48 +24,39 @@ public class TestKintoneAccessor {
|
|
24
24
|
public HashMap<String, FieldValue> createTestRecord() {
|
25
25
|
HashMap<String, FieldValue> testRecord = new HashMap<>();
|
26
26
|
|
27
|
-
testRecord = addField(testRecord, "文字列__1行", FieldType.SINGLE_LINE_TEXT, "test single text");
|
28
|
-
testRecord = addField(testRecord, "数値", FieldType.NUMBER, this.uniqueKey);
|
27
|
+
testRecord = TestHelper.addField(testRecord, "文字列__1行", FieldType.SINGLE_LINE_TEXT, "test single text");
|
28
|
+
testRecord = TestHelper.addField(testRecord, "数値", FieldType.NUMBER, this.uniqueKey);
|
29
29
|
this.uniqueKey += 1;
|
30
|
-
testRecord = addField(testRecord, "文字列__複数行", FieldType.MULTI_LINE_TEXT, "test multi text");
|
31
|
-
testRecord = addField(testRecord, "リッチエディター", FieldType.RICH_TEXT, "<div>test rich text<br /></div>");
|
30
|
+
testRecord = TestHelper.addField(testRecord, "文字列__複数行", FieldType.MULTI_LINE_TEXT, "test multi text");
|
31
|
+
testRecord = TestHelper.addField(testRecord, "リッチエディター", FieldType.RICH_TEXT, "<div>test rich text<br /></div>");
|
32
32
|
|
33
33
|
ArrayList<String> selectedItemList = new ArrayList<>();
|
34
34
|
selectedItemList.add("sample1");
|
35
35
|
selectedItemList.add("sample2");
|
36
|
-
testRecord = addField(testRecord, "チェックボックス", FieldType.CHECK_BOX, selectedItemList);
|
37
|
-
testRecord = addField(testRecord, "ラジオボタン", FieldType.RADIO_BUTTON, "sample2");
|
38
|
-
testRecord = addField(testRecord, "ドロップダウン", FieldType.DROP_DOWN, "sample3");
|
39
|
-
testRecord = addField(testRecord, "複数選択", FieldType.MULTI_SELECT, selectedItemList);
|
40
|
-
testRecord = addField(testRecord, "リンク", FieldType.LINK, "http://cybozu.co.jp/");
|
41
|
-
testRecord = addField(testRecord, "日付", FieldType.DATE, "2018-01-01");
|
42
|
-
testRecord = addField(testRecord, "時刻", FieldType.TIME, "12:34");
|
43
|
-
testRecord = addField(testRecord, "日時", FieldType.DATETIME, "2018-01-02T02:30:00Z");
|
36
|
+
testRecord = TestHelper.addField(testRecord, "チェックボックス", FieldType.CHECK_BOX, selectedItemList);
|
37
|
+
testRecord = TestHelper.addField(testRecord, "ラジオボタン", FieldType.RADIO_BUTTON, "sample2");
|
38
|
+
testRecord = TestHelper.addField(testRecord, "ドロップダウン", FieldType.DROP_DOWN, "sample3");
|
39
|
+
testRecord = TestHelper.addField(testRecord, "複数選択", FieldType.MULTI_SELECT, selectedItemList);
|
40
|
+
testRecord = TestHelper.addField(testRecord, "リンク", FieldType.LINK, "http://cybozu.co.jp/");
|
41
|
+
testRecord = TestHelper.addField(testRecord, "日付", FieldType.DATE, "2018-01-01");
|
42
|
+
testRecord = TestHelper.addField(testRecord, "時刻", FieldType.TIME, "12:34");
|
43
|
+
testRecord = TestHelper.addField(testRecord, "日時", FieldType.DATETIME, "2018-01-02T02:30:00Z");
|
44
44
|
|
45
45
|
ArrayList<Member> userList = new ArrayList<>();
|
46
46
|
userList.add(testman1);
|
47
47
|
userList.add(testman2);
|
48
|
-
addField(testRecord, "ユーザー選択", FieldType.USER_SELECT, userList);
|
48
|
+
TestHelper.addField(testRecord, "ユーザー選択", FieldType.USER_SELECT, userList);
|
49
49
|
ArrayList<Member> groupList = new ArrayList<>();
|
50
50
|
groupList.add(testgroup1);
|
51
51
|
groupList.add(testgroup2);
|
52
|
-
addField(testRecord, "グループ選択", FieldType.GROUP_SELECT, groupList);
|
52
|
+
TestHelper.addField(testRecord, "グループ選択", FieldType.GROUP_SELECT, groupList);
|
53
53
|
ArrayList<Member> orgList = new ArrayList<>();
|
54
54
|
orgList.add(testorg1);
|
55
55
|
orgList.add(testorg2);
|
56
|
-
addField(testRecord, "組織選択", FieldType.ORGANIZATION_SELECT, orgList);
|
56
|
+
TestHelper.addField(testRecord, "組織選択", FieldType.ORGANIZATION_SELECT, orgList);
|
57
57
|
return testRecord;
|
58
58
|
}
|
59
59
|
|
60
|
-
private HashMap<String, FieldValue> addField(HashMap<String, FieldValue> record, String code, FieldType type,
|
61
|
-
Object value) {
|
62
|
-
FieldValue newField = new FieldValue();
|
63
|
-
newField.setType(type);
|
64
|
-
newField.setValue(value);
|
65
|
-
record.put(code, newField);
|
66
|
-
return record;
|
67
|
-
}
|
68
|
-
|
69
60
|
@Test
|
70
61
|
public void testAccess() {
|
71
62
|
HashMap<String, FieldValue> testRecord = createTestRecord();
|
@@ -7,13 +7,14 @@ import org.embulk.spi.InputPlugin;
|
|
7
7
|
import org.embulk.test.TestingEmbulk;
|
8
8
|
import org.junit.Rule;
|
9
9
|
import org.junit.Test;
|
10
|
-
import org.junit.rules.ExpectedException;
|
11
10
|
|
12
11
|
import static org.junit.Assert.*;
|
13
12
|
|
14
13
|
public class TestKintoneClient {
|
15
14
|
private ConfigSource config;
|
15
|
+
private KintoneClient client = new KintoneClient();
|
16
16
|
private static final String BASIC_RESOURCE_PATH = "org/embulk/input/kintone/";
|
17
|
+
private static final String SUCCESS_MSG = "Exception should be thrown by this";
|
17
18
|
|
18
19
|
private static ConfigSource loadYamlResource(TestingEmbulk embulk, String fileName) {
|
19
20
|
return embulk.loadYamlResource(BASIC_RESOURCE_PATH + fileName);
|
@@ -28,8 +29,11 @@ public class TestKintoneClient {
|
|
28
29
|
public void checkClientWithUsernameAndPassword() {
|
29
30
|
config = loadYamlResource(embulk, "base.yml");
|
30
31
|
PluginTask task = config.loadConfig(PluginTask.class);
|
31
|
-
|
32
|
-
|
32
|
+
Exception e = assertThrows(Exception.class, ()-> {
|
33
|
+
client.validateAuth(task);
|
34
|
+
throw new Exception(SUCCESS_MSG);
|
35
|
+
});
|
36
|
+
assertEquals(SUCCESS_MSG, e.getMessage());
|
33
37
|
}
|
34
38
|
|
35
39
|
@Test
|
@@ -38,7 +42,7 @@ public class TestKintoneClient {
|
|
38
42
|
config.remove("username")
|
39
43
|
.remove("password");
|
40
44
|
PluginTask task = config.loadConfig(PluginTask.class);
|
41
|
-
ConfigException e = assertThrows(ConfigException.class, () ->
|
45
|
+
ConfigException e = assertThrows(ConfigException.class, () -> client.validateAuth(task));
|
42
46
|
assertEquals("Username and password or token must be provided", e.getMessage());
|
43
47
|
}
|
44
48
|
|
@@ -47,7 +51,7 @@ public class TestKintoneClient {
|
|
47
51
|
config = loadYamlResource(embulk, "base.yml");
|
48
52
|
config.remove("password");
|
49
53
|
PluginTask task = config.loadConfig(PluginTask.class);
|
50
|
-
ConfigException e = assertThrows(ConfigException.class, () ->
|
54
|
+
ConfigException e = assertThrows(ConfigException.class, () -> client.validateAuth(task));
|
51
55
|
assertEquals("Username and password or token must be provided", e.getMessage());
|
52
56
|
}
|
53
57
|
|
@@ -56,9 +60,7 @@ public class TestKintoneClient {
|
|
56
60
|
config = loadYamlResource(embulk, "base.yml");
|
57
61
|
config.remove("username");
|
58
62
|
PluginTask task = config.loadConfig(PluginTask.class);
|
59
|
-
ConfigException e = assertThrows(ConfigException.class, () ->
|
60
|
-
new KintoneClient(task);
|
61
|
-
});
|
63
|
+
ConfigException e = assertThrows(ConfigException.class, () -> client.validateAuth(task));
|
62
64
|
assertEquals("Username and password or token must be provided", e.getMessage());
|
63
65
|
}
|
64
66
|
|
@@ -69,7 +71,10 @@ public class TestKintoneClient {
|
|
69
71
|
.remove("password")
|
70
72
|
.set("token", "token");
|
71
73
|
PluginTask task = config.loadConfig(PluginTask.class);
|
72
|
-
|
73
|
-
|
74
|
+
Exception e = assertThrows(Exception.class, ()-> {
|
75
|
+
client.validateAuth(task);
|
76
|
+
throw new Exception(SUCCESS_MSG);
|
77
|
+
});
|
78
|
+
assertEquals(SUCCESS_MSG, e.getMessage());
|
74
79
|
}
|
75
80
|
}
|
@@ -1,27 +1,99 @@
|
|
1
1
|
package org.embulk.input.kintone;
|
2
2
|
|
3
|
+
import com.cybozu.kintone.client.model.app.form.FieldType;
|
4
|
+
import com.cybozu.kintone.client.model.record.GetRecordsResponse;
|
5
|
+
import com.cybozu.kintone.client.model.record.field.FieldValue;
|
6
|
+
|
7
|
+
import org.embulk.EmbulkTestRuntime;
|
8
|
+
import org.embulk.config.ConfigDiff;
|
3
9
|
import org.embulk.config.ConfigSource;
|
10
|
+
import org.embulk.config.TaskReport;
|
11
|
+
import org.embulk.config.TaskSource;
|
4
12
|
import org.embulk.spi.InputPlugin;
|
5
|
-
|
13
|
+
import org.embulk.spi.Schema;
|
14
|
+
import org.embulk.spi.TestPageBuilderReader.MockPageOutput;
|
15
|
+
import org.embulk.spi.time.Timestamp;
|
16
|
+
import org.embulk.spi.time.TimestampParser;
|
17
|
+
import org.embulk.spi.util.Pages;
|
6
18
|
import org.embulk.test.TestingEmbulk;
|
19
|
+
|
20
|
+
import org.junit.Before;
|
7
21
|
import org.junit.Rule;
|
8
22
|
import org.junit.Test;
|
9
23
|
|
24
|
+
import java.util.ArrayList;
|
25
|
+
import java.util.HashMap;
|
26
|
+
import java.util.List;
|
27
|
+
import java.util.stream.Collectors;
|
28
|
+
import java.util.stream.IntStream;
|
29
|
+
|
10
30
|
import static org.junit.Assert.*;
|
31
|
+
import static org.mockito.Mockito.*;
|
11
32
|
|
12
33
|
public class TestKintoneInputPlugin {
|
13
34
|
private ConfigSource config;
|
14
35
|
private static final String BASIC_RESOURCE_PATH = "org/embulk/input/kintone/";
|
36
|
+
private KintoneInputPlugin kintoneInputPlugin;
|
37
|
+
private KintoneClient kintoneClient;
|
38
|
+
private MockPageOutput output = new MockPageOutput();
|
39
|
+
private TimestampParser dateParser = TimestampParser.of("%Y-%m-%d", "UTC");
|
40
|
+
private TimestampParser timestampParser = TimestampParser.of("%Y-%m-%dT%H:%M:%S%z", "UTC");
|
15
41
|
|
16
42
|
private static ConfigSource loadYamlResource(TestingEmbulk embulk, String fileName) {
|
17
43
|
return embulk.loadYamlResource(BASIC_RESOURCE_PATH + fileName);
|
18
44
|
}
|
19
45
|
|
46
|
+
@Before
|
47
|
+
public void prepare(){
|
48
|
+
kintoneInputPlugin = spy(new KintoneInputPlugin());
|
49
|
+
kintoneClient = mock(KintoneClient.class);
|
50
|
+
doReturn(kintoneClient).when(kintoneInputPlugin).getKintoneClient();
|
51
|
+
}
|
52
|
+
@Rule
|
53
|
+
public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
|
54
|
+
|
20
55
|
@Rule
|
21
56
|
public TestingEmbulk embulk = TestingEmbulk.builder()
|
22
57
|
.registerPlugin(InputPlugin.class, "kintone", KintoneInputPlugin.class)
|
23
58
|
.build();
|
24
59
|
|
60
|
+
@Test
|
61
|
+
public void simpleTest(){
|
62
|
+
config = loadYamlResource(embulk, "base.yml");
|
63
|
+
PluginTask task = config.loadConfig(PluginTask.class);
|
64
|
+
Schema outputSchema = task.getFields().toSchema();
|
65
|
+
GetRecordsResponse response = createSampleData();
|
66
|
+
when(kintoneClient.getResponse(any(PluginTask.class))).thenReturn(response);
|
67
|
+
|
68
|
+
ConfigDiff configDiff = kintoneInputPlugin.transaction(config, new Control());
|
69
|
+
|
70
|
+
assertTrue(configDiff.isEmpty());
|
71
|
+
|
72
|
+
List<Object[]> outputRecords = Pages.toObjects(outputSchema, output.pages);
|
73
|
+
Object[] record1 = outputRecords.get(0);
|
74
|
+
|
75
|
+
Timestamp date1 = dateParser.parse("2020-01-01");
|
76
|
+
Timestamp timestamp1 = timestampParser.parse("2020-01-01T00:00:00Z");
|
77
|
+
|
78
|
+
assertEquals(2, outputRecords.size());
|
79
|
+
|
80
|
+
assertEquals("test single text", record1[0]);
|
81
|
+
assertEquals(1L, record1[1]);
|
82
|
+
assertEquals(1.111, record1[2]);
|
83
|
+
assertEquals(date1, record1[3]);
|
84
|
+
assertEquals(timestamp1, record1[4]);
|
85
|
+
|
86
|
+
Timestamp date2 = dateParser.parse("2020-02-02");
|
87
|
+
Timestamp timestamp2 = timestampParser.parse("2020-02-02T00:00:00Z");
|
88
|
+
|
89
|
+
Object[] record2 = outputRecords.get(1);
|
90
|
+
assertEquals("test single text2", record2[0]);
|
91
|
+
assertEquals(2L, record2[1]);
|
92
|
+
assertEquals(2.222, record2[2]);
|
93
|
+
assertEquals(date2, record2[3]);
|
94
|
+
assertEquals(timestamp2, record2[4]);
|
95
|
+
}
|
96
|
+
|
25
97
|
@Test
|
26
98
|
public void checkDefaultConfigValues() {
|
27
99
|
config = loadYamlResource(embulk, "base.yml");
|
@@ -37,4 +109,41 @@ public class TestKintoneInputPlugin {
|
|
37
109
|
assertFalse(task.getQuery().isPresent());
|
38
110
|
assertNotNull(task.getFields());
|
39
111
|
}
|
112
|
+
|
113
|
+
private GetRecordsResponse createSampleData(){
|
114
|
+
HashMap<String, FieldValue> record1 = new HashMap<>();
|
115
|
+
HashMap<String, FieldValue> record2 = new HashMap<>();
|
116
|
+
ArrayList<HashMap<String, FieldValue>> records = new ArrayList<>();
|
117
|
+
GetRecordsResponse response = new GetRecordsResponse();
|
118
|
+
|
119
|
+
record1 = TestHelper.addField(record1, "foo", FieldType.SINGLE_LINE_TEXT, "test single text");
|
120
|
+
record1 = TestHelper.addField(record1, "bar", FieldType.NUMBER, 1);
|
121
|
+
record1 = TestHelper.addField(record1, "baz", FieldType.NUMBER, 1.111);
|
122
|
+
record1 = TestHelper.addField(record1, "date", FieldType.DATE, "2020-01-01");
|
123
|
+
record1 = TestHelper.addField(record1, "datetime", FieldType.DATE, "2020-01-01T00:00:00Z");
|
124
|
+
records.add(record1);
|
125
|
+
|
126
|
+
record2 = TestHelper.addField(record2, "foo", FieldType.SINGLE_LINE_TEXT, "test single text2");
|
127
|
+
record2 = TestHelper.addField(record2, "bar", FieldType.NUMBER, 2);
|
128
|
+
record2 = TestHelper.addField(record2, "baz", FieldType.NUMBER, 2.222);
|
129
|
+
record2 = TestHelper.addField(record2, "date", FieldType.DATE, "2020-02-02");
|
130
|
+
record2 = TestHelper.addField(record2, "datetime", FieldType.DATE, "2020-02-02T00:00:00Z");
|
131
|
+
records.add(record2);
|
132
|
+
|
133
|
+
response.setRecords(records);
|
134
|
+
response.setTotalCount(2);
|
135
|
+
return response;
|
136
|
+
}
|
137
|
+
|
138
|
+
private class Control implements InputPlugin.Control
|
139
|
+
{
|
140
|
+
@Override
|
141
|
+
public List<TaskReport> run(final TaskSource taskSource, final Schema schema, final int taskCount)
|
142
|
+
{
|
143
|
+
List<TaskReport> reports = IntStream.range(0, taskCount)
|
144
|
+
.mapToObj(i -> kintoneInputPlugin.run(taskSource, schema, i, output))
|
145
|
+
.collect(Collectors.toList());
|
146
|
+
return reports;
|
147
|
+
}
|
148
|
+
}
|
40
149
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-input-kintone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- giwa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -46,10 +46,11 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- ".gitignore"
|
49
|
+
- ".travis.yml"
|
49
50
|
- LICENSE.txt
|
50
51
|
- README.md
|
51
52
|
- build.gradle
|
52
|
-
- classpath/embulk-input-kintone-0.1.
|
53
|
+
- classpath/embulk-input-kintone-0.1.2.jar
|
53
54
|
- classpath/gson-2.8.2.jar
|
54
55
|
- classpath/kintone-sdk-0.4.0.jar
|
55
56
|
- config/checkstyle/checkstyle.xml
|
@@ -64,6 +65,7 @@ files:
|
|
64
65
|
- src/main/java/org/embulk/input/kintone/KintoneInputColumnVisitor.java
|
65
66
|
- src/main/java/org/embulk/input/kintone/KintoneInputPlugin.java
|
66
67
|
- src/main/java/org/embulk/input/kintone/PluginTask.java
|
68
|
+
- src/test/java/org/embulk/input/kintone/TestHelper.java
|
67
69
|
- src/test/java/org/embulk/input/kintone/TestKintoneAccessor.java
|
68
70
|
- src/test/java/org/embulk/input/kintone/TestKintoneClient.java
|
69
71
|
- src/test/java/org/embulk/input/kintone/TestKintoneInputPlugin.java
|