用Java编写Embulk输出插件
首先
我已经注意到已经有一些用Ruby编写的Embulk插件出现了,并且Embulk的使用场景也逐渐增加。然而,我觉得用Java编写的插件还是相对较少。正好,我有机会编写一个从Embulk导出数据到Elasticsearch的输出插件,所以我将把这个插件的编写方法作为备忘录记录下来。
首先使用插件模版。
无论是用 Ruby 还是 Java 来创建插件,我认为首先要执行Embulk提供的new命令。New命令会自动生成用于插件开发所需的gradle脚本和Embulk本体所需的注册插件的脚本等。在Embulk中,根据开发哪个类别(output、input、filter等)的插件,扩展Embulk的点是不同的,而这些扩展的模板也会自动生成。
这次我们将使用Java来创建用于Elasticsearch输出的插件,指定Category为’java-output’,Name为’elasticsearch’并进行执行。
$ java -jar embulk.jar new java-output elasticsearch
确认插件类型的声明
只需要一个选项:通过执行上述的 new 命令,将创建一个名为 lib/embulk/output/elasticsearch.rb 的文件,这个文件是 Embulk 主体在启动时注册为可用插件所必需的描述。
Embulk::JavaPlugin.register_output(
:elasticsearch, "org.embulk.output.ElasticsearchOutputPlugin",
File.expand_path('../../../../classpath', __FILE__))
用户可以通过Embulk主程序读取这个声明,并在配置文件中指定名为’elasticsearch’的类型。
out:
type: elasticsearch
Embulk::JavaPlugin 类是 Embulk 主体的 lib/embulk/java_plugin.rb 文件。这里定义了一些类方法,如register_input和register_output。要将Java的输出插件注册到Embulk中,可以使用register_output。插件类型声明为:symbol类型的:elasticsearch,并同时传递实际插件的Java类名。
用Java编写Output Plugin
新的命令将创建一个名为 ‘org.embulk.output.ElasticsearchOutputPlugin’ 的类,该类将在Java中实现输出插件。要在Java中编写输出插件类,该类必须实现在embulk-core中的org.embulk.spi.OutputPlugin。当前的Elasticsearch输出插件实现较简单,没有实现resume和cleanup方法。为了至少可以在没有resume选项的情况下运行Embulk,我已经实现了transaction和open方法。在这里实现的transaction方法将在Embulk的LocalExecutor#doRun方法中调用。而open方法将在LocalExecutor#startProcessor中使用。
Open方法的返回类型是org.embulk.spi.TransactionalPageOutput,该对象是用来表示Embulk向其传递的数据应输出到何处的类。特别是,Embulk会调用TransactionalPageOutput的add(Page)方法,将数据传递给输出插件。传递的Page对象是多个记录的集合。使用PageReader逐条读取并将其输出到某个地方。Elasticsearch提供了批量API,客户端可以一次性对多个记录进行索引。Elasticsearch输出插件利用这个功能。
而且,在 Embulk 启动时,通过配置文件加载数据并将其导出到 Elasticsearch 集群中,可以通过选项方便地进行设置。为此,需要声明一个实现 org.embulk.config.Task 的类。
创建一个Java插件的宝石(gem)。
Embulk的插件不依赖于实现语言,而是通过gem进行分发。 Embulk可以轻松获取并使用在rubygems.org上发布的Embuk的插件。通过本文所述的new命令,gem的创建任务将自动声明在build.gradle中。通过执行gradle,将创建gem文件。
$ ./gradlew gem
将插件注册到Embulk核心
在Embulk-plugin-input的相关页面上已经详细说明了如何加载Embulk插件。
在开发过程中,试错是不可避免的。因此,在进行 Embulk 插件开发时,有时候希望能够快速地加载正在开发中的插件到 Embulk 主体中进行验证。通过 Embulk 的运行命令中的 -I 选项,可以实现将该插件加载到 Embulk 主体中进行测试,而无需创建该插件的 gem 文件。
$ java -jar embulk.jar run -I <path-to-plugin>/lib config.yml
在执行以上命令之前,需要先使用./gradlew classpath或./gradle gem等命令,预先获取依赖于插件的jar文件,并将其存储在classpath/目录下(2015年2月16日更新)。
如上所述,我们可以开发和测试Java插件。不仅仅是Ruby,如果Embulk插件能够不断地在Java上实现,那将是非常令人高兴的。此外,除了其他方法之外,我们也可以考虑将Java插件加载到Embulk中,如果有机会的话,我会记下笔记。