ActiveMQ Consumer插件开发笔记
源代码
https://github.com/tangwenixng/soyuan-activemq-plugin
概览
前提
该插件基于kettle 8.1.0.0-365
开发
如果是其他版本,不保证可用。(由于继承的BaseStreamingDialog
等父类会随版本而变化)
本插件模仿官方Kafka插件源码编写:
https://github.com/pentaho/big-data-plugin/tree/master/kettle-plugins/kafka
暂不支持topic,需要的可自行修改源码(工程量应该不大)。
必备模板
首先必须创建的4个类:
- ActiveMQConsumer extends BaseStreamStep implements StepInterface
- ActiveMQConsumerData extends TransExecutorData implements StepDataInterface
- ActiveMQConsumerDialog extends BaseStreamingDialog implements StepDialogInterface
- ActiveMQConsumerMeta extends BaseStreamStepMeta implements StepMetaInterface
注意这4个类继承的父类比较特殊,不同于一般的步骤插件继承的是BaseStep***
然后创建多语言(资源)配置文件:结构如下图所示
接下来将分别说明刚刚列举的4个类。
ActiveMQConsumerMeta
ActiveMQConsumerMeta
是非常重要的一个类。
- 可视化Dialog里看到的属性值(比如: Text框框)在点击了确认按钮时会保存到
ActiveMQConsumerMeta
中对应的成员变量的。当第一次打开步骤界面Dialog时(即open方法时-后面会讲到),也是从ActiveMQConsumerMeta
中读取成员变量赋值到Text框框中。 - 当在Kettle编辑界面点击了保存Save按钮时,会将
ActiveMQConsumerMeta
中的属性通过getXML()
方法写入到文件(ktr)中。当点击运行按钮时,kettle会调用loadXML()
将ktr文件内容读取到ActiveMQConsumerMeta
成员变量中。同理readRep和saveRep。
上面介绍了Meta类的主要工作,接着具体说明下代码中需要注意的点:
Step注解
@Step(
id = "ActiveMQConsumer",
name = "ActiveMQConsumer.TypeLongDesc",
description = "ActiveMQConsumer.TypeTooltipDesc",
image = "com/soyuan/steps/activemq/resources/activemq.svg",
categoryDescription = "i18n:org.pentaho.di.trans.step:BaseStep.Category.Streaming",
i18nPackageName = "com.soyuan.steps.activemq",
documentationUrl = "ActiveMQConsumer.DocumentationURL",
casesUrl = "ActiveMQConsumer.CasesURL",
forumUrl = "ActiveMQConsumer.ForumURL"
)
@InjectionSupported(localizationPrefix = "ActiveMQConsumerMeta.Injection.")
@step注解是定义步骤的规范,kettle会自动扫描此注解,并将它注入到插件容器内。
- id必须是全局唯一的
- name: 也就是我们在可视化界面中看到的插件名字。后面跟的
ActiveMQConsumer.TypeLongDesc
指向的是配置文件properties中的属性 @InjectionSupported(localizationPrefix = "ActiveMQConsumerMeta.Injection.")
中的ActiveMQConsumerMeta.Injection.
需要配合ActiveMQConsumerMeta
中的成员变量来使用。比如:
/**
* 连接地址
*/
@Injection( name = "BROKER_URL" )
private String brokerUrl;
这里的BROKER_URL
和刚刚的ActiveMQConsumerMeta.Injection.
搭配起来就成了ActiveMQConsumer.Injection.BROKER_URL
。
这个属性也是在配置文件properties中配置的
构造方法
public ActiveMQConsumerMeta() {
super();
...
setSpecificationMethod(ObjectLocationSpecificationMethod.FILENAME);
}
- 注意指定
setSpecificationMethod(ObjectLocationSpecificationMethod.FILENAME);
这里设置的ObjectLocationSpecificationMethod.FILENAME
值会在ActiveMQConsumerDialog.getData()
用到
接口方法
@Override
public StepInterface getStep(StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta, Trans trans) {
return new ActiveMQConsumer(stepMeta, stepDataInterface, copyNr, transMeta, trans);
}
@Override
public StepDataInterface getStepData() {
return new ActiveMQConsumerData();
}
这两个方法是接口必须实现的,按照模板来就行
成员变量
看代码注释
//固定用法,配合BaseMessages类从配置文件中读取配置
private static Class<?> PKG = ActiveMQConsumerMeta.class;
/**
* 以下静态变量用于定义xml中的标签tag
*/
public static final String BROKER_URL = "brokerUrl";
public static final String QUEUE_NAME = "queue";
public static final String TRANSFORMATION_PATH = "transformationPath";
public static final String BATCH_SIZE = "batchSize";
public static final String BATCH_DURATION = "batchDuration";
public static final String OUTPUT_FIELD_TAG_NAME = "OutputField";
public static final String INPUT_NAME_ATTRIBUTE = "input";
public static final String TYPE_ATTRIBUTE = "type";
public static final String ADVANCED_CONFIG = "advancedConfig" ;
private static final String CONFIG_OPTION = "option";
private static final String OPTION_PROPERTY = "property";
private static final String OPTION_VALUE = "value";
/**
* 连接地址
*/
@Injection( name = "BROKER_URL" )
private String brokerUrl;
/**
* 队列名称
*/
@Injection(name="QUEUE")
private String queue;
/**
* 注入的配置: 注意是transient
* 在哪赋值的-Dialog中
*/
@Injection(name =