Embulkプラグインのテストを楽にやりたい
EmbulkではJavaやRubyでプラグインを開発することができる。
自分は今のところJavaで開発しているので、それについて書いてみたい。
どうやってプラグインをテストする?
EmbulkのプラグインはRubyのgemとして配布される。
そして、embulk gem install ~ で簡単にインストールできる。
また、開発時には-Iオプションを使うとgemを作らなくてもプラグインを組み込んで実行することができる。
(参考:Java で Embulk Output Plugin を書く)
だが、JUnitとかでテストしたりデバッグしようとすると、プロセス起動するのはちょっと重いしめんどい。
できればJavaクラス内から実行したいところだ。
JavaからEmbulkを呼び出す
frsyukiさんによると、Embulkは他のJavaクラスからも呼び出せる。「EmbulkServiceをインスタンス化してInjectorを取り出し、あとはRunnerを参考に…」とのことだ。
自分はEclipseで開発しているが、この方法ならEclipse上でデバッグすることもできる!
しかし、当然この方法ではインストール済みのプラグインしか動かない。
どうやって開発中のプラグインを簡単に組み込むか、だ。
開発中のプラグインを組み込んでEmbulkを起動する
で、Embulkのソースを追って、プラグインを組み込むのはInjectedPluginSource.registerPluginToで、そこに必要なBinderインスタンスはModule.configureで渡されて、Moduleを登録するには…、などと調べて、結局下のようなソースでうまくいくようだ。
public class EmbulkPluginTester { private final Class<?> iface; private final String name; private final Class<?> impl; public EmbulkPluginTester(Class<?> iface, String name, Class<?> impl) { this.iface = iface; this.name = name; this.impl = impl; } public void run(String ymlPath) throws Exception { EmbulkService service = new EmbulkService(new EmptyConfigSource()) { protected Iterable<? extends Module> getAdditionalModules(ConfigSource systemConfig) { return Arrays.asList(new Module() { @Override public void configure(Binder binder) { InjectedPluginSource.registerPluginTo(binder, iface, name, impl); } }); } }; Injector injector = service.getInjector(); ConfigSource config = injector.getInstance(ConfigLoader.class).fromYamlFile(new File(ymlPath)); ExecSession session = new ExecSession(injector, config); LocalExecutor executor = injector.getInstance(LocalExecutor.class); ExecutionResult result = executor.run(session, config); }
使い方はこんな感じ。
// "filesplit"はymlのtypeに対応する EmbulkPluginTester tester = new EmbulkPluginTester(InputPlugin.class, "filesplit", LocalFileSplitInputPlugin.class); tester.run("/embulk/test.yml");
なお、EmptyConfigSourceのソースはこちら。nullを渡すとぬるぽで落ちるので、ダミーのクラスを作った。
これで、EmbulkのJARファイルと、開発中のプラグインをクラスパスに置けば、実行・デバッグできるはず。
Java | JDK 8u31 |
Embulk | 0.5.0 |
※ hiroysatoさんに教えて頂き-Iオプションを追記しました