注意: まだ書きかけです。
プラグインを開発する
このガイドでは、Embulkのプラグインを開発する方法を説明します。
新しいプラグインを作ることで、新規のクラウドサービスからデータを取得したり、新しいデータウェアハウスシステムにデータを出力できるようになります。
入力から出力まで全てのプラグインを開発する必要はありません。Embulkには既に多くのプラグインが提供されています。既存のプラグインでは足りない部分だけを開発すれば良いのです。
使用したEmbulkのバージョン
本ガイドで使用したEmbulkのバージョンは、0.8.9です。バージョン番号が異なる場合は、こちらのガイドどおりに動作しないことがあるかもしれません。その際はこちらのガイドを適宜修正するので、問題点をお知らせください。
Embulkプラグインの概要
開発言語(Java, JRuby)
Embulkのプラグインは、Javaまたは、JRuby(Java版Ruby)で開発することができます。
備考: いくつかのプラグインは、Scala(Java VM上で動く関数型言語)を使って作成されています。プラグインの開発にScalaを使いたい場合は、Qiitaの記事を参考にしてください。
開発できるプラグイン
現在Java, Rubyそれぞれの言語を使って作成できるプラグインは次のとおりです。
plugin | Java | Ruby |
---|---|---|
input | ○ | ○ |
file-input | ○ | × |
output | ○ | ○ |
file-output | ○ | × |
parser | ○ | ○ |
formatter | ○ | ○ |
decoder | ○ | × |
encoder | ○ | × |
executor | ○ | ○ |
inputとinput-file, outputとoutput-fileの違い
開発に必要な環境
- 開発に必要な環境
- OS : LinuxやOS X等のUNIX互換システム
- JDK: Java7以上のJDK SE ? (でいいのかな?)
- プラグインの公開
- Rubygems(http://rubygems.org)のアカウント
- Gem in a box (https://github.com/geminabox/geminabox)
OS
プラグイン開発に利用出来るOSは、LinuxやOSX等のUNIX互換のシステムを利用できます。
備考: Windowsを使って開発を行うことも可能ですが、幾つかの制限事項があります。Windowsを使っている人は、Cygwinを導入して開発をしていることが多いようです。
JDK
Java7以上のJDK SEが必要です。
Rubygemのアカウント
プラグインを作成すると、embulk-TYPE-NAME-X.Y.Z.gemというファイルが作成されます。TYPEやNAMEの内容はつぎのとおりです。
- TYPE: inputやoutputなどプラグインの種類名
- NAME: 作成したプラグインの名前(例、csv, bigquery)
- X.Y.Z: バージョン番号
gemファイルは、Rubyの世界で利用しているパッケージ管理システムです。gemパッケージを公開するんのがRubygems(https://rubygems.org)サイトです。 開発したプラグインを公開するためには、アカウントの作成が必要です。
諸般の事情で、作成したプラグインを限定した環境でのみ利用する場合は、Gem in a Box(https://github.com/geminabox/geminabox) というRubyのパッケージを使って、プライベートはRubygems環境を構築することができます。
チュートリアル
Java
embulk new
コマンドを使って、Java用のinputプラグインの雛形を作成します。
embulk new java-input java_example
2016-07-17 22:07:09.046 +0900: Embulk v0.8.9
Creating embulk-input-java_example/
Creating embulk-input-java_example/README.md
Creating embulk-input-java_example/LICENSE.txt
Creating embulk-input-java_example/.gitignore
Creating embulk-input-java_example/gradle/wrapper/gradle-wrapper.jar
Creating embulk-input-java_example/gradle/wrapper/gradle-wrapper.properties
Creating embulk-input-java_example/gradlew.bat
Creating embulk-input-java_example/gradlew
Creating embulk-input-java_example/config/checkstyle/checkstyle.xml
Creating embulk-input-java_example/config/checkstyle/default.xml
Creating embulk-input-java_example/build.gradle
Creating embulk-input-java_example/lib/embulk/input/java_example.rb
Creating embulk-input-java_example/src/main/java/org/embulk/input/java_example/JavaExampleInputPlugin.java
Creating embulk-input-java_example/src/test/java/org/embulk/input/java_example/TestJavaExampleInputPlugin.java
Plugin template is successfully generated.
Next steps:
$ cd embulk-input-java_example
$ ./gradlew package
Embulk new
コマンドは次のようなファイルを作成します。それぞれファイルの役割については、後ほど詳しく説明をします。
.
|-- LICENSE.txt
|-- README.md
|-- build.gradle
|-- config
| `-- checkstyle
| |-- checkstyle.xml
| `-- default.xml
|-- gradle
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
|-- lib
| `-- embulk
| `-- input
| `-- java_example.rb
`-- src
|-- main
| `-- java
| `-- org
| `-- embulk
| `-- input
| `-- java_example
| `-- JavaExampleInputPlugin.java
`-- test
`-- java
`-- org
`-- embulk
`-- input
`-- java_example
`-- TestJavaExampleInputPlugin.java
この状態で、embulk-input-java_example
ディレクトリに移動をして、./gradlew classpath
コマンド(Windowsの場合は、gradlew.bat classpath
)を実行します。
./gradlew classpath
:compileJava
警告: [options] ブートストラップ・クラスパスが-source 1.7と一緒に設定されていません
警告1個
:processResources UP-TO-DATE
:classes
:jar
:classpath
BUILD SUCCESSFUL
Total time: 7.149 secs
This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.10/userguide/gradle_daemon.html
TODO: このままだと入力例にならないので、コードの修正が必要
Ruby
embulk new
コマンドを使って、Ruby用のinputプラグインの雛形を作成します。
embulk new ruby-input ruby_example
2016-07-17 21:29:16.803 +0900: Embulk v0.8.9
Creating embulk-input-ruby_example/
Creating embulk-input-ruby_example/README.md
Creating embulk-input-ruby_example/LICENSE.txt
Creating embulk-input-ruby_example/.gitignore
Creating embulk-input-ruby_example/Rakefile
Creating embulk-input-ruby_example/Gemfile
Creating embulk-input-ruby_example/.ruby-version
Creating embulk-input-ruby_example/embulk-input-ruby_example.gemspec
Creating embulk-input-ruby_example/lib/embulk/input/ruby_example.rb
Plugin template is successfully generated.
Next steps:
$ cd embulk-input-ruby_example
$ bundle install # install one using rbenv & rbenv-build
$ bundle exec rake # build gem to be released
$ bundle exec embulk run config.yml # you can run plugin using this command
Embulk new
コマンドは次のようなファイルを作成します。それぞれファイルの役割については、後ほど詳しく説明をします。
.
|-- Gemfile
|-- LICENSE.txt
|-- README.md
|-- Rakefile
|-- embulk-input-ruby_example.gemspec
`-- lib
`-- embulk
`-- input
`-- ruby_example.rb
3 directories, 6 files
Javaと違い、Rubyの場合はコンパイルが不要です。
conf.yml
ファイルを、embulk new
コマンドを実行したディレクトリと同じ場所で、作成します。ファイルの中身は次のような形式です。
embulk new
で生成するテンプレートファイルは、option1
を必須オプションで、整数型であることを前提にしています。
in:
type: ruby_example
option1: 123
out:
type: stdout
作成した設定ファイルを指定して、embulk run
コマンドを実行してみましょう。runコマンドの引数として、-I embulプラグイン/lib
ディレクトリを指定することで、embulk gem
コマンドを使ってプラグインをインストールせずに、プラグインの動作を確認することができます。
実行結果は次のようになります。
embulk run -I embulk-input-ruby_example/lib conf.yml
2016-07-17 21:30:51.441 +0900: Embulk v0.8.9
2016-07-17 21:30:53.963 +0900 [INFO] (0001:transaction): Loaded plugin embulk/input/ruby_example from a load path
2016-07-17 21:30:54.025 +0900 [INFO] (0001:transaction): Using local thread executor with max_threads=8 / output tasks 4 = input tasks 1 * 4
2016-07-17 21:30:54.047 +0900 [INFO] (0001:transaction): {done: 0 / 1, running: 0}
example-value,1,0.1
example-value,2,0.2
2016-07-17 21:30:54.164 +0900 [INFO] (0001:transaction): {done: 1 / 1, running: 0}
2016-07-17 21:30:54.236 +0900 [INFO] (main): Committed.
2016-07-17 21:30:54.236 +0900 [INFO] (main): Next config diff: {"in":{},"out":{}}
Embulk new
コマンドがサンプルで生成するファイルは、options1の値を入力データとして利用していません。そこでソースコードを修正して、入力データにoptions1の値を利用するように修正をしましょう。
--- a/lib/embulk/input/ruby_example.rb
+++ b/lib/embulk/input/ruby_example.rb
@@ -46,8 +46,8 @@ module Embulk
end
def run
- page_builder.add(["example-value", 1, 0.1])
- page_builder.add(["example-value", 2, 0.2])
+ page_builder.add(["example-value", @option1, 0.1])
+ page_builder.add(["example-value", @option1, 0.2])
page_builder.finish
task_report = {}
修正後、embulk run
コマンドを実行すると、options1に指定した値を出力していることが確認できます。
embulk run -I embulk-input-ruby_example/lib conf.yml
2016-07-17 21:33:20.908 +0900: Embulk v0.8.9
2016-07-17 21:33:23.234 +0900 [INFO] (0001:transaction): Loaded plugin embulk/input/ruby_example from a load path
2016-07-17 21:33:23.281 +0900 [INFO] (0001:transaction): Using local thread executor with max_threads=8 / output tasks 4 = input tasks 1 * 4
2016-07-17 21:33:23.307 +0900 [INFO] (0001:transaction): {done: 0 / 1, running: 0}
example-value,123,0.1
example-value,123,0.2
2016-07-17 21:33:23.414 +0900 [INFO] (0001:transaction): {done: 1 / 1, running: 0}
2016-07-17 21:33:23.500 +0900 [INFO] (main): Committed.
2016-07-17 21:33:23.500 +0900 [INFO] (main): Next config diff: {"in":{},"out":{}}
-
各言語で開発できるプラグイン
-
プラグイン開発の流れ(テンプレート生成から作成したプラグインの公開まで)
-
マイグレーション(新しいバージョンへの対応)
プラグインを開発する(Java編)
プラグインの開発の準備(Java)
コーディングスタイルAirlist
EmbulkのJava関連のコードは、Prestoと同じコードスタイル(Airlift codestyle)で記述されています。幾つかのスタイルについて、実例を挙げて説明します。詳細についてはhttps://github.com/airlift/codestyleを参照してください。
空白
ifやwhileは、空白を開け、{
の前も空白を開けます。
次のような形式ではなく
if(x > 0){
次のように表記します。
if (x > 0) {
if分などの()の前後は、空白を入れないで記載します。
次のような形式ではなく
if ( x > 0 ) {
次のように表記します。
if (x > 0) {
elseやcatch, finallyは、独立した行にする。(※、つまり}
を独立した行にするということです)
次のような形式ではなく
} else if (x < 0) {
次のように表記します。
}
else if (x < 0) {
カンマの後は、スペースを入れます。
次のような形式ではなく
foo(boolean a,int x,int y,int z)
次のように表記します。
foo(boolean a, int x, int y, int z)
改行後は、空行を入れません。
次のような形式ではなく
package com.intellij.samples;
import com.intellij.idea.Main;
次のように表記します。
package com.intellij.samples;
import com.intellij.idea.Main;
GradleやIntelliJによるスタイルのチェック方法
コーディングスタイルに従っているかどうかを下記の手順で、確認することができます。
Gradleの設定とIntelliJ IDEA 15 CE(OSX) の設定それぞれについて解説します。
プラグイン内のコードスタイルをチェックする設定は、Embulk 0.8から利用できるようになっています。
なお、Embulkのプロジェクトではプラグイン作成者の方が小気味良いハックで目の前の問題を解決することも許されても良いという方針から、スタイルを厳密に守ることを重要視していません。プラグインを作られる方の好きなスタイルでプラグインを作るのも自由です。
Gradleでは、次の手順で設定をします。
- 設定
- チェックコマンドを実行
build.gradleの設定(embulk 0.8からは自動設定)
embulk 0.8からは、embulk newをすると、次の設定がbuild.gradleに追加されます。
embulk 0.8より前のプラグインでもembulk migrate path/to/plugin_dir
コマンドを実行すれば同じ設定が適用されます。
plugins {
// 略
id "checkstyle"
}
// 略
checkstyle {
configFile = file("${project.rootDir}/config/checkstyle/checkstyle.xml")
toolVersion = '6.14.1'
}
checkstyleMain {
configFile = file("${project.rootDir}/config/checkstyle/default.xml")
ignoreFailures = true
}
checkstyleTest {
configFile = file("${project.rootDir}/config/checkstyle/default.xml")
ignoreFailures = true
}
またチェックに使うファイルが次の場所に作成されます。
- config/checkstyle/default.xml: 緩いチェック
- config/checkstyle/checkstyle.xml より厳密なチェック
二つのファイルはチェックする内容が若干異なります。 例えば、default.xmlではimportの順序に関するチェックは行わないようになっています。
チェックコマンドを実行
gradlew <チェックの種類>
でチェックを行うことができます。
チェックは次の種類が利用できます。checkは、checkstyleMain
とcheckstyleTest
それぞれを実行します。
- check: 緩いチェックで、警告のみ
- checkstyleMain: プラグイン本体のチェック
- checkstyleTest: テストコードのスタイルチェック
- checkstyle: より厳密なチェック、スタイルに従わないとエラーになる。
checkstyle
の実行例はつぎのとおりです。
./gradlew checkstyle
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:checkstyleMain
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsFileInputPlugin.java:27: 'java.io.File' は上のインポート文から1行空けるべきです。
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsFileInputPlugin.java:180:45: ':' の前にホワイトスペースがありません。
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsFileInputPlugin.java:187:57: 名前 'rewind_seconds' はパターン '^[a-z][a-zA-Z0-9]*$' に一致しなければなりません。
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsPartialFile.java:3:8: 使用されないインポートです - org.apache.hadoop.fs.Path。
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsPartialFile.java:23:30: '{' は新しい行にあるべきです。
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsPartialFile.java:38: Blank line before closing brace
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsPartialFileInputStream.java:0: ファイルが新しい行で終了していません。
[ant:checkstyle] /path/to/embulk-input-hdfs/src/main/java/org/embulk/input/hdfs/HdfsPartialFileInputStream.java:48:40: 'cast' の後にホワイトスペースがありません。
:checkstyleMain FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':checkstyleMain'.
> Checkstyle rule violations were found. See the report at: file:///path/to/embulk-input-hdfs/build/reports/checkstyle/main.xml
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 2.97 secs
IntelliJ IDEA 15 CEの場合
Airlift.xmlをダウンロードして、~/Library/Preferences/IdeaIC15/codestyles/Airlift.xml として保存します。
[Preferences] -> [Editor] -> [Code style]でSchemaからAirliftが選択できるようになります。
ソースコードのフォーマット
Reformatting Source Code によると、Code
-> Reformat Code
で自動整形をしてくれます。
-
コーディングルール
-
IDE連携
-
スタイルチェック
Java
-
設定の取得
- 設定の取得方法
- デフォルト値
-
guessプラグイン
-
インプット
- ファイルインプットとインプットプラグイン
- transaction
- resume
- cleanup
- run
-
デコーダー
-
パーサー
-
フィルタ
-
フォーマッター
-
アウトプット
-
エンコーダー
-
エクゼキューター
-
エラーハンドリング
- リトライ
- 無限リトライから回避
-
テスト
プラグインを開発する(Ruby編)
- guessプラグイン
- インプット
- パーサー
- フィルタ
- アウトプット
- フォーマッター
- テスト