Apache Camel 开发指南
使用 Apache Camel 开发应用程序
摘要
使开源包含更多
红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看我们的 CTO Chris Wright 信息 。
部分 I. 实施企业集成模式
这部分论述了如何使用 Apache Camel 构建路由。它涵盖基本构建块和 EIP 组件。
第 1 章 为路由定义构建块
摘要
Apache Camel 支持两种替代 域特定语言 (DSL)来定义路由:Java DSL 和 Spring XML DSL。定义路由的基本构建块是 端点 和 处理器 ,其中处理器的行为通常由表达式或逻辑 predicates 修改。 Apache Camel 允许您使用各种不同语言定义表达式和 predicates。
1.1. 实施 RouteBuilder 类
概述
要使用
域特定语言
(DSL),您可以扩展
RouteBuilder
类并覆盖其
configure ()
方法(您可以在其中定义路由规则)。
您可以根据需要定义多个
RouteBuilder
类。每个类实例化一次,并使用
CamelContext
对象注册。通常,每个
RouteBuilder
对象的生命周期由您部署路由器的容器自动管理。
RouteBuilder 类
作为路由器开发人员,您的核心任务是实施一个或多个
RouteBuilder
类。您可以从以下两种替代
RouteBuilder
类继承:
org.apache.camel.builder.RouteBuilder
仅适用于
部署到任何
容器类型的通用
RouteBuilder
基础类。它包括在
camel-core
构件中。
org.apache.camel.spring.SpringRouteBuilder
WWN-将这个基本类特别适应 Spring 容器。特别是,它提供了对以下 Spring 特定功能的额外支持:在 Spring registry 中查找 Bean (使用
beanRef ()
Java DSL 命令)和事务(详情请参阅
事务指南
)。它包括在
camel-spring
工件中。
RouteBuilder
类定义了用于启动路由规则的方法(如
from ()、拦截器
()
和
exception ()
)。
实施 RouteBuilder
例 1.1 “实施 RouteBuilder 类”
显示最小的
RouteBuilder
实施。
configure ()
方法正文包含一个路由规则,每个规则都是一个 Java 语句。
例 1.1. 实施 RouteBuilder 类
import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { // Define routing rules here: from("file:src/data?noop=true").to("file:target/messages"); // More rules can be included, in you like. // ... 规则的格式为URL1。to (URL2)
指示路由器从目录src/data
读取文件并将其发送到目录目标/消息
。选项?noop=true
指示路由器保留(而不是删除)src/data
目录中的源文件。 当您将contextScan
与 Spring 或 Blueprint 搭配使用时,默认情况下,Apache Camel 将查找单例 Bean。但是,您可以打开旧行为,使其包含用新
选项包括NonSingletons 的原型
。
1.2. 基本 Java DSL 语法
什么是 DSL?
域特定语言(DSL)是设计用于特殊用途的小型语言。DSL 不必以逻辑方式完成,但需要足够的能力来描述在所选域中充分描述问题。通常,DSL 不需要 专用的解析程序、解释器或编译器。DSL 可在现有面向对象的主机语言的顶部 piggyback,提供的 DSL 构造图完全用于在主机语言 API 中进行构造。 在假设的 DSL 中请考虑以下命令序列:
command01; command02; command03;
您可以将这些命令映射到 Java 方法调用,如下所示:
command01().command02().command03()
甚至可以将块映射到 Java 方法调用。例如:
command01().startBlock().command02().command03().endBlock()
DSL 语法由主机语言 API 的数据类型隐式定义。例如,Java 方法的返回类型决定了您可以合法调用下一个方法(等同于 DSL 中的下一个命令)。
路由器规则语法
Apache Camel 定义用于定义路由规则
的路由器 DSL
。您可以使用此 DSL 在
RouteBuilder.configure ()
实施的正文中定义规则。
图 1.1 “本地路由规则”
显示了用于定义本地路由规则的基本语法概述。
图 1.1. 本地路由规则

本地规则始终以
(("
EndpointURL
")
方法开头,该方法指定路由规则的消息源(
消费者端点
)。然后,您可以向规则(如
filter ()
)添加任意处理器链。您通常通过
to ("
EndpointURL
")
方法结束该规则,该方法为通过该规则传递的消息指定目标(
制作者端点
)。但是,通常不需要使用
to ()
的规则结束。另一种在规则中指定消息目标的方法。
您还可以使用特殊处理器类型(如拦截器()、
exception ()
或
errorHandler
启动规则)来定义全局路由规则。全局规则不在本指南范围内。
()
使用者和制作者
本地规则始终首先定义消费者端点,使用
from ("
EndpointURL
")
,而且通常(但并非总是)通过定义制作者端点(使用
to ("
EndpointURL
")
)结束。端点 URL
EndpointURL
可以使用部署时配置的任何组件。例如,您可以使用文件端点、
file:MyMessageDirectory
、Apache CXF 端点、
cxf:MyServiceName
或 Apache ActiveMQ 端点
activemq:queue:MyQName
。有关组件类型的完整列表,请参阅
Apache Camel 组件参考
。
Exchanges
Exchange
对象
由一个消息组成,由元数据提供。交换在 Apache Camel 中至关重要,因为交换是通过路由规则传播消息的标准表单。交换的主要拥塞如下:
在消息
您的应用程序器中,由交换封装的当前消息。随着交换通过路由进行,可以修改此消息。因此,在路由开始时的
In
消息通常与路由末尾的
In
消息
不同
。
org.apache.camel.Message
类型提供了消息的通用模型,包括以下部分:
务必要意识到,这是消息
的通用
模型。Apache Camel 支持各种协议和端点类型。因此,
无法
标准化消息正文或邮件标题的格式。例如,JMS 消息的正文将具有与 HTTP 消息正文或 Web 服务消息正文完全不同的格式。因此,正文和标头被声明为
对象类型
。然后,正文和标头的内容由创建交换实例的端点(即,端点会出现在
from ()
命令中)。
out
message chronyc-ocpis 是用于回复消息的临时区域,或者用于转换的消息。某些处理节点(特别是
to ()
命令)可以通过将
In
消息视为请求来修改当前的消息,将其发送到制作者端点,然后从该端点接收回复。然后,将回复消息插入到交换中的
Out
message 插槽中。
通常,如果当前节点设置了
Out
消息,则 Apache Camel 会在将其传递到路由中的下一节点之前修改交换:旧的
In
message 将被丢弃,而
Out
消息将移到
In
message 插槽中。因此,回复会成为新的当前消息。有关 Apache Camel 在路由中如何连接节点的详情,请参考
第 2.1 节 “Pipeline 处理”
。
然而,有一个特殊情况处理
Out
消息。如果路由开始时的消费者端点预期是回复消息,则路由末尾的
Out
消息会被视为消费者端点的回复消息(如果最终节点
必须创建
Out
消息或消费者端点挂起)。
消息交换模式(MEP)指代路由中交换和端点之间的交互,如下所示:
消费者端点
TOKEN-将消费者端点创建原始交换,设置 MEP 的初始值。初始值指示使用者端点是否需要接收回复(例如,
InOut
MEP)还是非(例如,
InOnly
MEP)。
制作者端点
有助于 MEP 影响交换与路由相关的制作者端点(例如,当交换通过了
to ()
节点时)。例如,如果当前 MEP 为
InOnly
,则
to ()
节点不会预期从端点接收回复。有时您需要更改当前 MEP,以自定义与制作者端点的交换交互。如需了解更多详细信息,请参阅
第 1.4 节 “Endpoints”
。
交换属性的 propertiesLogForwarder-cmpia 列表,包含当前消息的元数据。
消息交换模式
通过使用
Exchange
对象,可轻松将消息处理分散到
不同的消息交换模式
。例如,异步协议可能会定义一个 MEP,其包含一条从消费者端点流到制作者端点(一个
InOnly
MEP)的消息。另一方面,一个 RPC 协议可能定义一个 MEP,它由请求消息和回复消息(an
InOut
MEP)组成。目前,Apache Camel 支持以下 MEP:
InOnly
RobustInOnly
InOut
In optionalOut
OutOnly
RobustOutOnly
OutIn
OutOptionalIn
其中,这些消息交换模式由枚举类型(
org.apache.camel.ExchangePattern
)中的常数表示。
分组的交换
有时,使用一个交换来封装多个交换实例会很有用。为此,您可以使用
一组交换
。分组的交换实例本质上是一个交换实例,其中包含了
Exchange.GROUPED_EXCHANGE
Exchange
属性中存储的 Exchange 对象的
java.util.List
。有关如何使用分组交换的示例,请参考
第 8.5 节 “聚合器”
。
处理器
是路由中的节点,可以访问和修改通过路由的交换流。处理器可以使用
表达式或
predicate
参数来修改其行为。例如,
图 1.1 “本地路由规则”
中显示的规则包含一个
filter ()
处理器,它采用
xpath ()
predicate 作为其参数。
表达式和 predicates
表达式(评估字符串或其他数据类型)和 predicates (评估为 true 或 false)通常作为内置处理器类型的参数发生。例如,以下过滤器规则传播
In
消息,只有
foo
标头等于 value
bar
:
from("seda:a").filter(header("foo").isEqualTo("bar")).to("seda:b");
这里的过滤器由 predicate、
header ("foo").isEqualTo ("bar")
限定的位置。要根据消息内容构建更复杂的 predicates 和表达式,您可以使用其中一个表达式和 predicate 语言(请参阅
第 II 部分 “路由表达式和专用语言”
)。
1.3. Spring XML 文件中的路由器架构
命名空间
路由器 schema并查看 XML DSL DSL-youbelongs 到以下 XML 模式命名空间:
http://camel.apache.org/schema/spring
指定架构位置
路由器模式的位置通常指定为
http://camel.apache.org/schema/spring/camel-spring.xsd
,它引用了 Apache 网站中架构的最新版本。例如,Apache Camel Spring 文件的 root
Bean
元素通常配置为
例 1.2 “指定路由器架构位置”
。
例 1.2. 指定路由器架构位置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <!-- Define your routing rules here --> </camelContext> </beans>
运行时架构位置
在运行时,Apache Camel
不会从
Spring 文件中指定的 schema 位置下载路由器模式。相反,Apache Camel 会自动从
camel-spring
JAR 文件的根目录获取 schema 副本。这样可确保解析 Spring 文件的 schema 版本始终与当前运行时版本匹配。这很重要,因为 Apache Web 站点上发布的 schema 的最新版本可能不与您当前使用的运行时版本不匹配。
使用 XML 编辑器
通常,建议您使用全功能 XML 编辑器编辑 Spring 文件。XML 编辑器的自动完成功能使编写符合路由器架构的 XML 更容易,如果 XML 不正确,则编辑器可能会立即警告您。
XML 编辑器
通常
依赖于从您在
xsi:schemaLocation
属性中指定的位置下载 schema。为了确保您使用了正确的模式版本 whilst 编辑,最好选择
camel-spring.xsd
文件的特定版本。例如,要编辑 2.3 版本 Apache Camel 的 Spring 文件,您可以按照如下所示修改 Bean 元素:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring-2.3.0.xsd">
编辑完成后,将改回到默认的 camel-spring.xsd
。要查看当前可以下载的 schema 版本,请导航至网页 http://camel.apache.org/schema/spring。
1.4. Endpoints
概述
Apache Camel 端点是路由中消息的源和接收器。端点是非常典型的构建块:它必须满足的唯一要求是它充当消息源(制作者端点)或作为消息接收器(消费者端点)。因此,Apache Camel 支持多种不同端点类型,范围从支持端点(如 HTTP)到简单计时器端点,如 Quartz,它会定期生成 dummy 消息。Apache Camel 的主要优势之一是:添加实施新端点类型的自定义组件相对容易。
端点 URI
端点 URI 识别 端点 ,它有以下常规形式:
scheme:contextPath[?queryOptions]
URI
架构
标识了一个协议,如
http
,而
contextPath
提供由协议解释的 URI 详情。另外,大多数方案都允许您定义以以下格式指定的
查询选项、查询Options
:
?option01=value01&option02=value02&...
例如,以下 HTTP URI 可用于连接到 Google 搜索引擎页面:
http://www.google.com
以下文件 URI 可用于读取出现在
C:\temp\src\data
目录下的所有文件:
file://C:/temp/src/data
并非每个 方案 都代表协议。有时,一种 方案 只能访问有用的实用程序,如计时器。例如,以下 Timer 端点 URI 每秒钟生成一个一次交换(=1000 毫秒)。您可以使用此计划路由中的活动。
timer://tickTock?period=1000
使用 Long Endpoint URI
有时,因为提供的所有配置信息,端点 URI 可能太长。在 JBoss Fuse 6.2 中,您可以采取两种方法来提高您处理长度 URI 的工作。
- 配置 9 月端点
-
您可以单独配置端点,来自路由,使用它们的简写 ID 引用端点。
<camelContext ...> <endpoint id="foo" uri="ftp://foo@myserver"> <property name="password" value="secret"/> <property name="recursive" value="true"/> <property name="ftpClient.dataTimeout" value="30000"/> <property name="ftpClient.serverLanguageCode" value="fr"/> </endpoint> <route> <from uri="ref:foo"/> </route> </camelContext>
您还可以在 URI 中配置一些选项,然后使用
property
属性指定附加选项(或者用于覆盖 URI 的选项)。<endpoint id="foo" uri="ftp://foo@myserver?recursive=true"> <property name="password" value="secret"/> <property name="ftpClient.dataTimeout" value="30000"/> <property name="ftpClient.serverLanguageCode" value="fr"/> </endpoint>
- 跨 New Lines 分割端点配置
-
您可以使用新行来分割 URI 属性。
<route> <from uri="ftp://foo@myserver?password=secret& recursive=true&ftpClient.dataTimeout=30000& ftpClientConfig.serverLanguageCode=fr"/> <to uri="bean:doSomething"/> </route>
注意您可以在每行中指定一个或多个选项,每个选项用 和 分隔。
在 URI 中指定时间
许多 Apache Camel 组件都有选项,其值为持续时间(例如,指定超时值等等)。默认情况下,此类时间段选项通常指定为纯数字,该数字被解释为毫秒的时间段。但是 Apache Camel 还支持更易读的语法,它可让您以小时、分钟和秒表示周期。正式来说,人类可读的时间段是一个遵循以下语法的字符串:
[NHour(h|hour)][NMin(m|minute)][NSec(s|second)]
在方括号 中每个术语
[]
都是可选的,使用符号
(A|B)
,表示
A
和
B
是 alternatives。
例如,您可以使用 45 分钟期限配置
计时器
端点,如下所示:
from("timer:foo?period=45m") .to("log:foo");
您还可以使用小时、分钟和第二个单元的任意组合,如下所示:
from("timer:foo?period=1h15m") .to("log:foo"); from("timer:bar?period=2h30s") .to("log:bar"); from("timer:bar?period=3h45m58s") .to("log:bar");
在 URI 选项中指定原始值
默认情况下,您在 URI 中指定的选项值会自动 URI 编码。在某些情况下这是不需要的行为。例如,在设置 password 选项时,最好在
没有 URI 编码的情况下
传输原始字符字符串。
可以通过使用语法
RAW (
RawValue
)
指定选项值来关闭 URI 编码。例如,
from("SourceURI") .to("ftp:joe@myftpserver.com?password=RAW(se+re?t&23)&binary=true")
在本例中,密码值将作为字面值传输,
se+re?t&23
。
不区分大小写的 enum 选项
某些端点 URI 选项会映射到 Java
枚举常量。例如,Log 组件的
level
选项,该选项可取
enum
值、
INFO
、
WARN
、WARN、
ERROR
等。这个类型转换不区分大小写,因此以下任意备选方案可用于设置 Log producer 端点的日志级别:
<to uri="log:foo?level=info"/> <to uri="log:foo?level=INfo"/> <to uri="log:foo?level=InFo"/>
指定 URI 资源
从 Camel 2.17 中,基于 XSLT 等资源的组件可以使用
ref:
作为前缀,从注册表加载资源文件。
例如,
如果myvelocityscriptbean
和
mysimplescriptbean
是注册表中两个 Bean 的 ID,您可以使用这些 Bean 的内容,如下所示:
Velocity endpoint: ------------------ from("velocity:ref:myvelocityscriptbean").<rest_of_route>. Language endpoint (for invoking a scripting language): ----------------------------------------------------- from("direct:start") .to("language:simple:ref:mysimplescriptbean") Where Camel implicitly converts the bean to a String.
Apache Camel 组件
每个 URI 架构 都映射到 Apache Camel 组件 ,其中 Apache Camel 组件本质上是一个端点工厂。换句话说,若要使用特定类型的端点,您必须在运行时容器中部署对应的 Apache Camel 组件。例如,要使用 JMS 端点,您将在容器中部署 JMS 组件。 Apache Camel 提供各种不同组件,允许您将应用程序与各种传输协议和第三方产品集成。例如,一些常用的组件有:文件、JMS、CXF (Web 服务)、HTTP、Jetty、Direct 和 Mock。有关支持组件的完整列表,请参阅 Apache Camel 组件文档 。 大多数 Apache Camel 组件单独打包到 Camel 内核。如果使用 Maven 构建应用程序,您可以轻松地将组件(及其第三方依赖项)添加到应用程序中,只需添加对相关组件工件的依赖。例如,要包含 HTTP 组件,您可以在项目 POM 文件中添加以下 Maven 依赖项:
<!-- Maven POM File --> <properties> <camel-version>{camelFullVersion}</camel-version> </properties> <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-http</artifactId> <version>${camel-version}</version> </dependency> </dependencies>
以下组件内置于 Camel 内核(在
camel-core
构件中),因此它们始终可用:
dataset
Properties
timer