embulk v0.10 API를 사용한 개인 노트
개시하다
Embulk 플러그 인은 0.9 ~ 0.10 노트에 해당합니다.
기본적으로 여기Java plugins to catch up with Embulk v0.10 from v0.9에 쓴 내용을 읽으면 됩니다.평소에 자바를 쓰지 않는 자기가 쓰는 노트(눈에 띄는 게 있으면 꼭 알려주세요)
나는 선생님께서 가르쳐 주신 물건을 한데 모으고 싶다
골대
새 API 플러그인
gradle-embulk-plugins
v0.API 개발 플러그인 10개를 사용하려면gradle 플러그인으로 제공되는 gradle-embulk-plugins를 사용해야 합니다. 이 플러그인은gradle 버전 6이 필요하기 때문에gradle 버전을 먼저 제공해야 합니다.
gradle의 업데이트 방법
gradle의 버전은 6입니다.엑스를 이용하다.최근gradle7을 발매할 것 같지만
gradle-embulk-plugins
7.0에 대응하지 못해 6.6에 불과하다.X 계열의 버전을 이용하다.최신 버전여기. 확인
./gradlew wrapper --gradle-version 6.8.2
처럼 집행하다.build.다시 쓰기gradle
읽으면서 How to migrate old-style build.gradle of your Embulk plugins 플러그인을 다시 쓰는
build.gradle
.쓴 대로 가면 된다.4. Add required testCompile if depending on embulk-core:0.9.22+.
에 관한 부분은embulk-0.10 이후에 다음과 같이 기재한다. testCompile "org.embulk:embulk-deps:0.10.26"
다음 부분은 루비게이지 대신 마븐 센트럴에서 플러그인을 가져올 수 있는 메커니즘을 사용합니다.플러그인을 Maven Central에 업로드하기 전에 먼저 의견을 달아보는 것이 좋습니다(제 생각에는)//publishing {
// publications {
// embulkPluginMaven(MavenPublication) { // Publish it with "publishEmbulkPluginMavenPublicationToMavenRepository".
// from components.java // Must be "components.java". The dependency modification works only for it.
// }
// }
// repositories {
// maven {
// url = "${project.buildDir}/mavenPublishLocal"
// }
// }
//}
자바를 컴파일할 때 deprecated의 경고를 출력하기 위해 다음과 같은 설정을 추가합니다.tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation" << "-Xlint:unchecked"
}
gradle-embulk-plugins
는 플러그인 로드에 필요한 루비 파일을 자동으로 생성하며 기존 플러그인의 파일プラグイン名.rb
이 필요하지 않습니다.여러 가지 상황(Ruby 구현
guess
이 있는 경우 다음과 같은 기술을 통해 독자적인 Ruby 파일을gem에 포함할 수 있다.gem {
generateRubyCode = false // Avoiding generate lib/embulk/parser/jsonpath.rb
into("lib/embulk/parser/") {
from "lib/embulk/parser/jsonpath.rb"
}
into("lib/embulk/guess/") {
from "lib/embulk/guess/jsonpath.rb"
}
Java 우선 적용
import 다시 쓰기
기존
embulk-core
에서 총집합된 클래스는 embulk-util-config
와 embulk-util-timestamp
등 다른 라이브러리로 분할되었다.import 문장을 각각 바꿔야 합니다.아래의 각본을 만들어 기계적으로 변환한다.
#!/bin/bash
set -ue
fatal(){
echo "Fatal Error: $*" >&2
exit 1
}
if [ ! -d src ] ; then
fatal "invalid exec directory"
fi
find src -name '*.java' -print0 | xargs -0 \
perl -i -pe 's/import org.embulk.config.Config;/import org.embulk.util.config.Config;/;
s/import org.embulk.config.ConfigDefault;/import org.embulk.util.config.ConfigDefault;/;
s/import org.embulk.config.Task;/import org.embulk.util.config.Task;/;
s/import org.embulk.spi.ColumnConfig;/import org.embulk.util.config.units.ColumnConfig;/;
s/import org.embulk.spi.SchemaConfig;/import org.embulk.util.config.units.SchemaConfig;/;
s/import com.google.common.base.Optional;/import java.util.Optional;/;
s/import org.embulk.spi.util.FileInputInputStream;/import org.embulk.util.file.FileInputInputStream;/;
s/import org.embulk.spi.time.TimestampParser;/import org.embulk.util.timestamp.TimestampFormatter;/;
'
Exec.getModelManager()
향후 소멸할 것으로 예상되지만, 현재는 엑시클인터넷을 활용해 당분간 회피할 수 있다.ModelManager는 조만간 삭제되며 다른 쓰기 방식을 사용해야 합니다.
Exec.getModelManager()
ExecInternal.getModelManager
ExecInternal의build를 사용합니다.gradle에서compileOnly "embulk-core"
가 필요하지만 그 자체는 추천하지 않습니다.dependencies에 embulk-core
를 넣는 것을 최대한 피해야 한다는 것이다.테스트에서 ExecInternal을 잠시 사용할 수 있음(v0.11 개발 시 논의할 모습)
다음 기술은 테스트를 통해서만 ExecInternal을 활용하는 설정입니다.
dependencies {
testCompile "org.embulk:embulk-core:0.10.28"
}
loadConfig, loadTask
ConfigMapper
, TaskMapper
는 각 종류에서 제공하는 map
방법을 이용한다.@@ -43,6 +46,7 @@ public class JsonpathParserPlugin
{
private static final Logger logger = LoggerFactory.getLogger(JsonpathParserPlugin.class);
+ private static final ConfigMapperFactory CONFIG_MAPPER_FACTORY = ConfigMapperFactory.builder().addDefaultModules().build();
private static final Configuration JSON_PATH_CONFIG = Configuration
.builder()
@@ -94,18 +98,22 @@ public class JsonpathParserPlugin
@Override
public void transaction(ConfigSource config, ParserPlugin.Control control)
{
- PluginTask task = config.loadConfig(PluginTask.class);
+ final ConfigMapper configMapper = CONFIG_MAPPER_FACTORY.createConfigMapper();
+ final PluginTask task = configMapper.map(config, PluginTask.class);
Schema schema = getSchemaConfig(task).toSchema();
- control.run(task.dump(), schema);
+ control.run(task.toTaskSource(), schema); // v0.10 only
}
@Override
public void run(TaskSource taskSource, Schema schema,
FileInput input, PageOutput output)
{
- PluginTask task = taskSource.loadTask(PluginTask.class);
+ final TaskMapper taskMapper = CONFIG_MAPPER_FACTORY.createTaskMapper();
+ final PluginTask task = taskMapper.map(taskSource, PluginTask.class);
+
고정 의존 라이브러리
고정 사용
./gradlew dependencies --write-locks
버전의 의존 관계파일을 잠그는 자세가 있어야 한다
build.만약gradle을 적절하게 설정했다면 아래 줄을 포함해야 한다
javax.validation:validation-api:1.1.0.Final
com.fasterxml.jackson.core:jackson-annotations:2.6.7
com.fasterxml.jackson.core:jackson-core:2.6.7
com.fasterxml.jackson.core:jackson-databind:2.6.7
com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.6.7
이상적이지 않은 설정
만약 의존 관계가 적절하지 않다면, 예를 들면 다음과 같다.
embulk-util-config
사용com.fasterxml.jackson.core:jackson-databind
의 2.6.7다른 라이브러리의 의존 관계의 영향
2.6.7
으로 대체2.6.7.2
되었다.+--- org.embulk:embulk-util-aws-credentials:0.4.0
| +--- org.embulk:embulk-util-config:0.1.1 -> 0.2.1
| | +--- javax.validation:validation-api:1.1.0.Final
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.6.7
| | +--- com.fasterxml.jackson.core:jackson-core:2.6.7
| | +--- com.fasterxml.jackson.core:jackson-databind:2.6.7 -> 2.6.7.2 (*)
| | \--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.6.7
| | +--- com.fasterxml.jackson.core:jackson-core:2.6.7
| | \--- com.fasterxml.jackson.core:jackson-databind:2.6.7 -> 2.6.7.2 (*)
이러한 출력을 진행한 경우 잠금 파일에 기록2.6.7
이 아니라 기록2.6.7.2
이다.com.fasterxml.jackson.core:jackson-databind:2.6.7.2
이러한 상황에서 적절하게 이용exclude
하여 의존관계에서 봉인을 배제하고 상기 응당한 자세를 형성하여 설정build.gradle 기술의 기본 방침
embulk-util-config
에서 exclude를 진행한 상황에서comple을 명확하게 묘사하여 상술한 모든 가방을 진입시켰다잭슨 버전.
이하 이외의 잭슨 시스템의 라이브러리 진입
embulkPluginRuntime.lockfile
한 경우(Embalk v0.9.23도 이동)도 반드시 2.6.7
에 고정해야 한다.취소(Embalk v0.9 계열 v10.31 이하) v10.32(미발행) 이상 또는 v0.11(미발행)만 대상으로 했다면
2.6.7
이외에도 가능하다.2.6.7
이외의 잭슨, 엠벌크 v0을 넣어도.9 가지 동작도 있지만 장담은 없다.운이 좋다.com.fasterxml.jackson.core:jackson-annotations
com.fasterxml.jackson.core:jackson-core
com.fasterxml.jackson.core:jackson-databind
com.fasterxml.jackson.datatype:jackson-datatype-jdk8
잭슨
아래의 진입
embulkPluginRuntime.lockfile
의 경우 어느 라이브러리에서 이런 진입을 낳고 사용하는지 밝혀야 한다exclude
등은 다음과 같이 고정된 버전이다.취소(Embalk v0.9 계열 v10.31 이하) v10.32(미발행) 이상 또는 v0.11(미발행)만 대상으로 한다면 다른 버전도 가능하다.Embalk v0 버전이 추가된 경우에도 마찬가지입니다.9 가지 동작도 있지만 장담은 없다.운이 좋다.
com.google.guava:guava
=> 18.0
org.apache.commons:commons-lang3
=> 3.4
joda-time:joda-time
=> 2.9.2
org.apache.bval:bval-jsr303
=> 0.5
자주 exclude로 만들어서 다시 넣을 수 없는 것
이하 입장
embulkPluginRuntime.lockfile
한 경우exclude
는 입장하지 않아야 한다.org.slf4j:slf4j-api
org.msgpack:msgpack-core
버전 고정을 위한 exclude의 경우
버전 고정
slf4j-api
을 위해 상기msgpack-core
과 exclude
를 제외한 버전을 고정하려면 compile "..."
로 지정한 버전을 다시 설치하는 것을 잊지 마세요.잊어버리면 새로운 엠바크 버전은 움직이지 않는다.(이 라이브러리는 필요한 의존 관계가 없기 때문)
여기까지
API 호환성
문서의
since
섹션이 0.10인 경우 새 API, v0이 작성됩니다.9 를 사용할 때는 이 방법을 사용할 수 없다TypeModule
다음 오류가 발생하면 ConfigMapperFactory를 만들 때 add Type Module이 필요합니다.(embulk-util-config:0.3.0 기본값,
TypeModule
도 추가되었기 때문에 이 수정은 필요 없습니다.)Caused by: java.lang.IllegalArgumentException:
Can not construct instance of org.embulk.spi.type.Type,
problem: abstract types either need to be mapped to concrete types,
private static final ConfigMapperFactory CONFIG_MAPPER_FACTORY = ConfigMapperFactory
.builder()
.addDefaultModules()
.addModule(new TypeModule()) // <-- これ
.build();
탈구바
다시 쓰기 ImmutableMap
diff --git a/src/main/java/org/embulk/parser/jsonpath/JsonpathParserPlugin.java b/src/main/java/org/embulk/parser/jsonpath/JsonpathParserPlugin.java
index 1946175..5bc9746 100644
--- a/src/main/java/org/embulk/parser/jsonpath/JsonpathParserPlugin.java
+++ b/src/main/java/org/embulk/parser/jsonpath/JsonpathParserPlugin.java
@@ -2,8 +2,10 @@ package org.embulk.parser.jsonpath;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
+
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Optional;
-import com.google.common.collect.ImmutableMap;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.InvalidJsonException;
import com.jayway.jsonpath.JsonPath;
@@ -186,15 +188,15 @@ public class JsonpathParserPlugin
private Map<Column, String> createJsonPathMap(PluginTask task, Schema schema)
{
- ImmutableMap.Builder<Column, String> builder = ImmutableMap.builder();
+ Map<Column, String> columnMap = new HashMap<>();
for (int i = 0; i < schema.size(); i++) {
ColumnConfig config = getSchemaConfig(task).getColumn(i);
JsonpathColumnOption option = config.getOption().loadConfig(JsonpathColumnOption.class);
if (option.getPath().isPresent()) {
- builder.put(schema.getColumn(i), option.getPath().get());
+ columnMap.put(schema.getColumn(i), option.getPath().get());
}
}
- return builder.build();
+ return Collections.unmodifiableMap(columnMap);
}
private void skipOrThrow(DataException cause, boolean stopOnInvalidRecord)
ImmutableSet
diff --git a/src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java b/src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java
index d846ffe..d5aef46 100644
--- a/src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java
+++ b/src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java
@@ -3,8 +3,9 @@ package org.embulk.parser.jsonpath;
import com.fasterxml.jackson.databind.JsonNode;
import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
im#port java.util.Optional;
-import com.google.common.collect.ImmutableList;
import org.embulk.parser.jsonpath.JsonpathParserPlugin.PluginTask;
import org.embulk.parser.jsonpath.JsonpathParserPlugin.TypecastColumnOption;
import org.embulk.spi.Column;
@@ -31,8 +32,8 @@ public class ColumnVisitorImpl
implements ColumnVisitor
{
private static final JsonParser JSON_PARSER = new JsonParser();
- private static final List<String> BOOL_TRUE_STRINGS = ImmutableList.of("true", "1", "yes", "on", "y", "t");
- private static final List<String> BOOL_FALSE_STRINGS = ImmutableList.of("false", "0", "no", "off", "n", "f");
+ private static final List<String> BOOL_TRUE_STRINGS = Collections.unmodifiableList(Arrays.asList("true", "1", "yes", "on", "y", "t"));
+ private static final List<String> BOOL_FALSE_STRINGS = Collections.unmodifiableList(Arrays.asList("false", "0", "no", "off", "n", "f"));
protected final PluginTask task;
protected final Schema schema;
Throwable
diff --git a/embulk-core/src/main/java/org/embulk/EmbulkEmbed.java b/embulk-core
/src/main/java/org/embulk/EmbulkEmbed.java
index af0e88f4..2f98c9b2 100644
--- a/embulk-core/src/main/java/org/embulk/EmbulkEmbed.java
+++ b/embulk-core/src/main/java/org/embulk/EmbulkEmbed.java
@@ -5,7 +5,6 @@ import static com.google.common.base.Preconditions.checkState;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
-import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
@@ -277,7 +276,10 @@ public class EmbulkEmbed {
try {
injector.destroy();
} catch (Exception ex) {
- throw Throwables.propagate(ex);
+ if (ex instanceof RuntimeException) {
+ throw (RuntimeException) ex;
+ }
+ throw new RuntimeException(ex);
}
}
테스트
embulk 0.1.10-0.1.29까지
-L
와-I
의 선택 행위는 0.9와 다르다.embulk 0.1.30에서 이런 행위를 수정하였다
참조여기.(추후 추가)
0.9와의 호환성
v0.embulk 0.9로 이동하는 동안 다음 오류가 발생한 경우 10API 작성
org.embulk.exec.PartialExecutionException: java.lang.RuntimeException: java.lang.NoSuchMethodError: org.embulk.spi.Buffer: method <init>()V not found
at org.embulk.exec.BulkLoader$LoaderState.buildPartialExecuteException(BulkLoader.java:340)
at org.embulk.exec.BulkLoader.doRun(BulkLoader.java:566)
at org.embulk.exec.BulkLoader.access$000(BulkLoader.java:35)
at org.embulk.exec.BulkLoader$1.run(BulkLoader.java:353)
at org.embulk.exec.BulkLoader$1.run(BulkLoader.java:350)
at org.embulk.spi.Exec.doWith(Exec.java:22)
at org.embulk.exec.BulkLoader.run(BulkLoader.java:350)
at org.embulk.EmbulkEmbed.run(EmbulkEmbed.java:242)
at org.embulk.EmbulkRunner.runInternal(EmbulkRunner.java:291)
at org.embulk.EmbulkRunner.run(EmbulkRunner.java:155)
at org.embulk.cli.EmbulkRun.runSubcommand(EmbulkRun.java:431)
at org.embulk.cli.EmbulkRun.run(EmbulkRun.java:90)
at org.embulk.cli.Main.main(Main.java:64)
build.gradle
에 다음 항목을 추가하여 구축합니다.버전은 0.1.3 이후여야 합니다.dependencies {
// ... snip ..
compile "org.embulk:embulk-util-file:0.1.3"
Task
TimestampFormatter.Task
// From org.embulk.spi.time.TimestampFormatter.Task
@Config("default_timezone")
@ConfigDefault("\"UTC\"")
public String getDefaultTimeZoneId();
// From org.embulk.spi.time.TimestampFormatter.Task
@Config("default_timestamp_format")
@ConfigDefault("\"%Y-%m-%d %H:%M:%S.%6N %z\"")
public String getDefaultTimestampFormat();
LineEncoder.Task
// From org.embulk.spi.util.LineEncoder.Task
@Config("charset")
@ConfigDefault("\"utf-8\"")
public Charset getCharset();
// From org.embulk.spi.util.LineEncoder.Task
@Config("newline")
@ConfigDefault("\"CRLF\"")
public Newline getNewline();
Reference
이 문제에 관하여(embulk v0.10 API를 사용한 개인 노트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/hiroysato/articles/b910af4c581bdb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)