Java/Kotlinでembulk-pluginを作る

[Ateam Lifestyle Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ateam-lifestyle)の7日目は株式会社エイチームライフスタイル @engabesi が担当します。

## はじめに
embulkのpluginを開発する機会があったのですが、
その際に検証方法等の情報が散らばっていて時間がかかったのでまとめます

また、今回作るのはembulk **v0.9** 対応のプラグインです
v0.11, v1.0対応は行っていませんのでご容赦ください

また、pluginの開発に使える言語は`JRuby`か`Java`、どちらかを使用できるのですが、
**v0.11** からは`Java`を推奨しているので今回は`Java`を使います

## 環境
* Mac Big Sur
* Java 1.8.0.292
* embulk 0.9.23

## インストール
コマンド類に関してはWindows、Dockerなどご自分の環境に合わせてください
以下Macの場合

embulkはJavaアプリケーションなのでJavaをインストールします
また、embulk0.9はJava8のみ対応のため、Java8を入れてください
私は`jenv`を使っています
jenvの導入等に関しては他の方の記事をご参照ください

```:terminal
$ jenv versions

  system
  1.8
* 1.8.0.292
  11
  11.0
  11.0.7
  openjdk64-1.8.0.292
  openjdk64-11.0.7
```

次にembulkをインストールします

```:terminal
$ curl --create-dirs -o ~/.embulk/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
$ chmod +x ~/.embulk/bin/embulk
$ echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc

$ embulk --versions
embulk 0.9.23
```

ちなみに執筆現在0.9の最新は0.9.24ですが、この手順だと0.9.23が入ります
0.9.24にする場合、後に登場する`embulk-core`のバージョンに0.9.24がなく手動で対応する必要がありますのでご注意ください

## セットアップ

次はembulk-pluginの開発環境を構築して検証を行える状態にします

(任意)今回の環境を構築するディレクトリを用意します

```:terminal
$ mkdir test-embulk-plugins
$ cd test-embulk-plugins
```

embulkにはテスト用の環境を用意してくれるコマンドがありますのでそれを使います

まずseedを作ります

```:terminal
$ embulk example ./seed
$ ls -la
total 0
drwxr-xr-x   3 h-2911  staff   96 12  6 13:21 .
drwxr-xr-x@ 29 h-2911  staff  928 12  6 13:20 ..
drwxr-xr-x   4 h-2911  staff  128 12  6 13:21 seed
```

`embulk example`実行時にコマンドのサジェストが出ると思うのでそれに従って進めます

```:terminal
$ embulk guess ./seed/seed.yml -o config.yml
$ embulk preview config.yml
$ embulk run config.yml
```

無事最後の`run`コマンドが動作すればテスト用embulk環境の構築は完了です

続いて本題のpluginの初期構築を行います
今回はJavaのinput-pluginを作成するのでoptionに`java-input`を指定します
JRubyやfilterプラグイン等、他のケースは[公式のガイド](https://dev.embulk.org/customization.html)をご参照ください

```:terminal
$ embulk new java-input test-plugin
```

上記コマンド実行後にサジェストされるコマンドを実行します
このコマンドがビルドコマンドになります
```:terminal
$ cd embulk-input-test_plugin
$ ./gradlew package
$ cd ..
```

`BUILD SUCCESSFUL`を確認したら一度この仮作成pluginを通して先程のテスト用embulk環境を走らせます

まずはテスト用のconfig.ymlを書き換えます

```yaml:./config.yml
in:
  type: test_plugin
  option1: 1
  parser:
    type: csv
  columns:
    - { name: column1, type: string }
    - { name: column2, type: string }
out: {type: stdout}

```

configで先程のpluginを指定、その後下記コマンドを実行

```:terminal
$ embulk run -L ./embulk-input-test_plugin/ config.yml
```

実行結果で`TestPluginInputPlugin.run method is not implemented yet`が表示されていれば問題なくpluginを使用できています

## 実装

`hello world`の文字列を返すだけの雑実装をします

```java:./embulk-input-test_plugin/src/main/java/org/embulk/input/test_plugin/TestPluginInputPlugin.java
// ==== 中略 ====
    @Override
    public TaskReport run(TaskSource taskSource,
            Schema schema, int taskIndex,
            PageOutput output)
    {
        PluginTask task = taskSource.loadTask(PluginTask.class);

        PageBuilder pageBuilder = new PageBuilder(Exec.getBufferAllocator(), schema,output);
        pageBuilder.setString(0, "hello");
        pageBuilder.setString(1, "world!!");
        pageBuilder.addRecord();
        pageBuilder.finish();
        return Exec.newTaskReport();
    }
// ==== 中略 ====
```

```:terminal
$ embulk run -L ./embulk-input-test_plugin/ config.yml

~中略~
hello,world!!
~中略~
```

動作することが確認できました
後は各々好きなように実装してpluginを作っていきましょう!

## Tips

### Kotlinにする
やっぱりJava系はKotlinで書きたいですよね!!!
基本的に`build.gradle`を書き換えるだけで大丈夫ですが、注意点があります
embulk v0.9のgradleはバージョンが`4.1`と低く、最新のkotlinは導入できませんので、`1.3.50`を入れます

```gradle:build.gradle
plugins {
    id "com.jfrog.bintray" version "1.1"
    id "com.github.jruby-gradle.base" version "1.5.0"
    id "java"
+   id "org.jetbrains.kotlin.jvm" version "1.3.50"
    id "checkstyle"
}
// === 中略 ===
dependencies {
    compile  "org.embulk:embulk-core:0.9.23"
    provided "org.embulk:embulk-core:0.9.23"
    // compile "YOUR_JAR_DEPENDENCY_GROUP:YOUR_JAR_DEPENDENCY_MODULE:YOUR_JAR_DEPENDENCY_VERSION"
+   compile "org.jetbrains.kotlin:kotlin-stdlib"
    testCompile "junit:junit:4.+"
}
// === 中略 ===
```

先程編集していた`TestPluginInputPlugin.java`を`TestPluginInputPlugin.kt`にして実装をKotlinに書き換えます
IntelliJだと右クリックからポチっとするだけでConvertしてくれます
IntelliJはいいぞ

## 最後に
明日は @asasigure さんによる記事です
お楽しみに!