01. 路由定义构建块

第1章 路由定义构建块

摘要

Apache Camel支持两种用于定义路由的领域域专用语言(DSL):Java DSL和Spring XML DSL。定义路由的基本构建块是端点处理器,其中处理器的行为通常通过表达式或逻辑判断进行修改。Apache Camel使您可以使用多种不同的语言来定义表达式和判断。

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 —该基类特别适合于Spring容器。特别是,它为以下特定于Spring的功能提供了额外的支持:在Spring注册表中查找bean(使用beanRef()Java DSL命令)和事务(有关详细信息,请参见事务指南)。它在camel-spring工件中提供。

RouteBuilder用于启动你的路由规则类中定义的方法(例如from()intercept()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.
  // ...
  }
}

规则的形式指示路由器从目录中读取文件并将它们发送到目录。该选项指示路由器将源文件保留(而不是删除)目录中。 from(*URL1*).to(*URL2*)``src/data``target/messages``?noop=true``src/data

注意

当您将contextScanwith和Spring或Blueprint一起使用以过滤RouteBuilder类时,默认情况下,Apache Camel将查找单例bean。但是,您可以打开旧的行为,以包含使用new选项限定范围的原型includeNonSingletons

1.2. 基本Java DSL语法

什么是DSL?

特定领域语言(DSL)是为特殊目的而设计的一种迷你语言。DSL不必在逻辑上完整,但需要足够的表达能力来充分描述所选域中的问题。通常,DSL并没有要求一个专门的解析器,翻译,编译或。如果DSL构造可以清晰地映射到宿主语言API中的构造,则DSL可以搭载在现有的面向对象宿主语言之上。

考虑假设的DSL中的以下命令序列:

command01;
command02;
command03;

您可以将这些命令映射到Java方法调用,如下所示:

command01().command02().command03()

您甚至可以将块映射到Java方法调用。例如:

command01().startBlock().command02().command03().endBlock()

DSL语法由主机语言API的数据类型隐式定义。例如,Java方法的返回类型决定了您可以合法地调用next(相当于DSL中的next命令)的方法。

路由规则语法

Apache Camel定义了用于定义路由规则的路由DSL。您可以使用此DSL在实现主体中定义规则RouteBuilder.configure()图1.1“本地路由规则”概述了用于定义本地路由规则的基本语法。

图1.1. 本地路由规则

image.png

本地规则始终以from("*EndpointURL*")方法开头,该方法指定路由规则的消息源(消费者端点)。然后,您可以在规则中添加任意长的处理器链(例如filter())。通常,您可以使用to("*EndpointURL*")方法来结束规则,该方法指定通过规则的消息的目标(生产者端点)。但是,不一定总是要以to()结束规则。有其他方法可以在规则中指定消息目标。

注意

您还可以定义一个全局路由规则,第一步是用一种特殊的处理器类型的规则(如intercept()exception()errorHandler())。全局规则不在本指南的范围内。

消费者和生产者

本地规则始终通过使用from("*EndpointURL*")方法定义消费者端点开始,通常(但并非总是)通过使用to("*EndpointURL*")方法定义生产者端点结束。端点URL EndpointURL可以使用在部署时配置的任何组件。例如,您可以使用文件端点file:MyMessageDirectory,Apache CXF端点cxf:MyServiceName,或Apache ActiveMQ端点activemq:queue:MyQName。有关组件类型的完整列表,请参见《Apache Camel组件参考》

交换

一个交换对象包括一个消息时,由元数据增强的。交换在Apache Camel中至关重要,因为交换是通过路由规则传播消息的标准形式。交换的主要组成部分如下:

  • In消息-是由交换包封当前消息。随着交换通过路由的进行,可以修改此消息。因此,In在一个路由的开始消息通常是not作为同一In消息到达路线的终点。该org.apache.camel.Message类型提供消息的通用模型,包括以下部分:

    • Body.
    • Headers.
    • Attachments.

    重要的是要意识到这是消息的通用模型。Apache Camel支持多种协议和端点类型。因此,它是not可能以规范的消息主体或邮件头的格式。例如,JMS消息的主体与HTTP消息或Web服务消息的主体具有完全不同的格式。因此,主体和标头被声明为Object类型。然后,主体和标头的原始内容由创建交换实例的端点(即出现在from()命令中的端点)确定。

  • Out消息-是答复消息或已转换消息的临时保留区域。某些处理节点(特别是to()命令)可以通过将 In消息视为请求,将其发送到生产者端点,然后从该端点接收答复来修改当前消息。然后将回复消息插入交换机中的 Out消息插槽。

    通常,如果当前节点已设置Out消息,则Apache Camel在将交换传递到路由中的下一个节点之前,将交换修改如下:将旧的In消息丢弃,并将Out消息移至In消息插槽。因此,答复成为新的当前消息。有关Apache Camel如何在路由中将节点连接在一起的详细讨论,请参见第2.1节“管道处理”

    但是,在一种特殊情况下,对Out消息的处理方式有所不同。如果路由起点处的使用者终结点希望收到回复消息,则将路线末尾的Out消息视为使用者终结点的回复消息(而且,在这种情况下,最终节点必须创建一Out消息或消费终端将挂起)。

  • 消息交换模式(MEP)-影响交换和路由中的端点之间的交互,如下所示:

    • 消费者端点 -创建原始交换的消费者端点设置MEP的初始值。初始值指示使用者端点是否期望接收答复(例如, InOut MEP)(例如, InOnly MEP)。
    • 生产者端点 — MEP影响交换沿路由遇到的生产者端点(例如,当交换通过to()节点时)。例如,如果当前的MEP是 InOnly,那么to()节点将不会期望收到来自端点的答复。有时您需要更改当前的MEP,以自定义交换与生产者端点的交互。有关更多详细信息,请参见第1.4节“端点”
  • Exchange属性-包含当前消息元数据的命名属性列表。

消息交换模式

使用Exchange对象可以轻松地将消息处理概括为不同的消息交换模式。例如,异步协议可能会定义一个MEP,该MEP由一条从消费者端点流向生产者端点(InOnly MEP)的消息组成。另一方面,RPC协议可能会定义由请求消息和回复消息(InOut MEP)组成的MEP。当前,Apache Camel支持以下MEP:

  • InOnly
  • RobustInOnly
  • InOut
  • InOptionalOut
  • OutOnly
  • RobustOutOnly
  • OutIn
  • OutOptionalIn

这些消息交换模式由枚举类型中的常量表示org.apache.camel.ExchangePattern

分组交换

有时具有封装多个交换实例的单个交换会很有用。为此,您可以使用分组交换。分组交换本质上是一个交换实例,其中包含存储在交换属性中java.util.ListExchange对象Exchange.GROUPED_EXCHANGE。有关如何使用分组交换的示例,请参见第8.5节“聚合器”

处理器

处理器是在可以访问和修改通过路由交换的流的路由的节点。处理器可以采用表达式判断参数来修改其行为。例如,图1.1“本地路由规则”中显示的规则包括一个filter()xpath()判断为其参数的处理器。

表达式和判断

表达式(评估为字符串或其他数据类型)和判断(评估为true或false)经常作为内置处理器类型的参数出现。例如,以下过滤规则仅在标头等于value的情况下传播in消息: foo``bar

from("seda:a").filter(header("foo").isEqualTo("bar")).to("seda:b");

如果过滤器由判断限定,则header("foo").isEqualTo("bar")。要基于消息内容构造更复杂的判断和表达式,可以使用一种表达式和判断语言(请参阅第II部分,“路由表达式和判断语言”)。

1.3. Spring XML文件中的路由结构

命名空间

定义XML DSL的路由模式属于以下XML模式名称空间:

http://camel.apache.org/schema/spring

指定结构位置

路由模式的位置通常指定为http://camel.apache.org/schema/spring/camel-spring.xsd,它引用Apache网站上模式的最新版本。例如,beans通常按示例1.2“指定路由器模式位置”中所示配置Apache Camel Spring文件的根元素。

范例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">
    <!-- 在此处定义路由规则 -->
  </camelContext>
</beans>

运行时结构位置

在运行时,Apache的骆驼也不会下载从Spring 文件中指定架构位置路由器架构。相反,Apache Camel会自动从camel-springJAR文件的根目录中提取模式的副本。这样可以确保用于解析Spring文件的架构版本始终与当前运行时版本匹配。这很重要,因为在Apache网站上发布的架构的最新版本可能与您当前使用的运行时版本不匹配。

使用XML编辑器

通常,建议您使用功能全面的XML编辑器来编辑Spring文件。XML编辑器的自动完成功能使编写符合路由器架构的XML变得更加容易,并且如果XML格式不正确,编辑器可以立即向您发出警告。

XML编辑器通常确实依赖从您在xsi:schemaLocation属性中指定的位置下载模式。为了确保在编辑时使用正确的架构版本,通常最好选择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完成编辑后,请更改回默认值。要查看当前可以下载哪些模式版本,请浏览至Web页面,网址为http://camel.apache.org/schema/spring

1.4. 端点

概览

Apache Camel端点是路由中消息的源和接收者。端点是一种非常通用的构建块:它必须满足的唯一要求是它充当消息源(生产者端点)或消息接收器(消费者端点)。因此,Apache Camel支持多种不同的端点类型,从协议支持端点(例如HTTP)到简单计时器端点(例如Quartz),这些端点以固定的时间间隔生成虚拟消息。Apache Camel的主要优势之一是,添加实现新端点类型的自定义组件相对容易。

端点URI

端点由端点URI标识,端点URI具有以下一般形式:

scheme:contextPath[?queryOptions]

URI 方案标识协议,例如http,并且contextPath提供该协议解释的URI详细信息。此外,大多数方案都允许您定义查询选项queryOptions,这些选项以以下格式指定:

?option01=value01&option02=value02&...

例如,以下HTTP URI可用于连接到Google搜索引擎页面:

http://www.google.com

以下文件URI可用于读取C:\temp\src\data目录下出现的所有文件:

file://C:/temp/src/data

并非每个方案都代表一个协议。有时,方案仅提供对有用工具的访问,例如计时器。

例如,以下计时器端点URI每秒钟(= 1000毫秒)生成一次交换。您可以使用它来计划路线中的活动。

timer:// tickTock?period = 1000

使用长端点URI

由于提供的所有随附配置信息,有时端点URI可能变得很长。从JBoss Fuse 6.2起,您可以采用两种方法使使用较长URI的工作更易于管理。

  • 分别配置端点

    您可以单独配置端点,并且可以使用路由的速记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>
    
  • 跨新行拆分端点配置

    您可以使用新行来分割URI属性。

    <route>
      <from uri="ftp://foo@myserver?password=secret&amp;
               recursive=true&amp;ftpClient.dataTimeout=30000&amp;
               ftpClientConfig.serverLanguageCode=fr"/>
      <to uri="bean:doSomething"/>
    </route>
    

注意

您可以在每行上指定一个或多个选项,每个选项之间用分隔&amp;

在URI中指定时间段

许多Apache Camel组件都有其值为时间段的选项(例如,用于指定超时值,等等)。默认情况下,此类时间段选项通常指定为纯数字,该值解释为毫秒时间段。但是Apache Camel还支持时间段的可读性更高的语法,使您可以用小时,分钟和秒来表示时间段。形式上,人类可读的时间段是一个符合以下语法的字符串:

[NHour(h|hour)][NMin(m|minute)][NSec(s|second)]

方括号中的每个术语[]都是可选的,而符号(A|B)则表示AB是替代方案。

例如,可以将timer端点配置为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编码。在某些情况下,这是不良行为。例如,在设置密码选项时,最好传输原始字符串而不使用 URI编码。

通过使用语法指定选项值可以关闭URI编码。例如, RAW(*RawValue*)

from("SourceURI")
 .to("ftp:joe@myftpserver.com?password=RAW(se+re?t&23)&binary=true")

在此示例中,密码值作为文字值传输se+re?t&23

不区分大小写的枚举选项

一些端点URI选项被映射到Java enum常量。例如,level日志组件,它可以采取的选项enum值,INFOWARNERROR,等。此类型转换不区分大小写,因此可以使用以下任何替代方法来设置日志生产者端点的日志记录级别:

<to uri="log:foo?level=info"/>
<to uri="log:foo?level=INfo"/>
<to uri="log:foo?level=InFo"/>

指定URI资源

从Camel 2.17开始,基于资源的组件(例如XSLT,Velocity)可以通过ref:用作前缀从注册表中加载资源文件。

例如,ifmyvelocityscriptbean并且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组件,您可以将以下Maven依赖项添加到项目POM文件中:

<!-- 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工件中),因此它们始终可用:

  • Bean
  • Browse
  • Dataset
  • Direct
  • File
  • Log
  • Mock
  • Properties
  • Ref
  • SEDA
  • Timer
  • VM

消费者端点

消费者端点是出现在路由开始处的端点(即,在from()DSL命令)。换句话说,消费者端点负责启动路由中的处理:它创建一个新的交换实例(通常基于它已接收或获得的某些消息),并提供一个线程来处理其余的交换。

例如,以下JMS使用者端点将消息拉出payments队列并在路由中对其进行处理:

from("jms:queue:payments")
  .process(SomeProcessor)
  .to("TargetURI");

或者等效地,在Spring XML中:

<camelContext id="CamelContextID"
              xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="jms:queue:payments"/>
    <process ref="someProcessorId"/>
    <to uri="TargetURI"/>
  </route>
</camelContext>

某些组件是消费者-即,它们只能用于定义消费者端点。例如,Quartz组件专门用于定义消费者端点。以下Quartz端点每秒(1000毫秒)生成一个事件:

from("quartz://secondTimer?trigger.repeatInterval=1000")
  .process(SomeProcessor)
  .to("TargetURI");

如果愿意,可以使用fromF()Java DSL命令将端点URI指定为格式字符串。例如,要将用户名和密码替换为FTP端点的URI,可以使用Java编写路由,如下所示:

fromF("ftp:%s@fusesource.com?password=%s", username, password)
  .process(SomeProcessor)
  .to("TargetURI");

其中,第一次出现的%s是用username字符串的值替换,而第二次出现的%s是用password字符串的值替换。此字符串格式化机制String.format()由C printf()函数提供,并且与C 函数提供的格式化相似。有关详细信息,请参见java.util.Formatter

生产者端点

生产者端点是出现在路由端点中间或在所述尾部(例如,在to()DSL命令)。换句话说,生产者端点接收现有的交换对象,并将交换的内容发送到指定的端点。

例如,以下JMS生产者端点将当前交换的内容推送到指定的JMS队列中:

from("SourceURI")
  .process(SomeProcessor)
  .to("jms:queue:orderForms");

或等效地在Spring XML中:

<camelContext id="CamelContextID" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURI"/>
    <process ref="someProcessorId"/>
    <to uri="jms:queue:orderForms"/>
  </route>
</camelContext>

某些组件生产者 ,也就是说,它们只能用于定义生产者端点。例如,HTTP端点专门用于定义生产者端点。

from("SourceURI")
  .process(SomeProcessor)
  .to("http://www.google.com/search?hl=en&q=camel+router");

如果愿意,可以使用toF()Java DSL命令将端点URI指定为格式字符串。例如,要将自定义Google查询替换为HTTP URI,可以使用Java编写路由,如下所示:

from("SourceURI")
  .process(SomeProcessor)
  .toF("http://www.google.com/search?hl=en&q=%s", myGoogleQuery);

%s用您的自定义查询字符串替换 出现的地方myGoogleQuery。有关详细信息,请参见java.util.Formatter

1.5. 处理器

概览

为了使路由能够执行比简单地将消费者端点连接到生产者端点更有趣的事情,您可以在路由中添加处理器。处理器是一种命令,您可以将其插入路由规则中,以对流经该规则的消息执行任意处理。如表1.1“ Apache Camel处理器”所示,Apache Camel提供了多种不同的处理器。

表1.1。Apache骆驼处理器

Java DSL XML DSL 描述
aggregate() aggregate 第8.5节“聚合器”:创建一个聚合器,它将多个传入的交换合并到一个交换中。
aop() aop 使用面向方面的编程(AOP)在指定的子路径之前和之后进行工作。
bean()beanRef() bean 通过在Java对象(或bean)上调用方法来处理当前交换。请参见第2.4节“ Bean集成”
choice() choice 第8.1节“基于内容的路由器”:使用whenotherwise子句根据交换内容选择特定的子路由。
convertBodyTo() convertBodyTo 入栈消息正文转换为指定的类型。
delay() delay 第8.9节“分层”:延迟交换到路由的后半部分的传播。
doTry() doTry 创建用于处理异常,使用try / catch块doCatchdoFinallyend条款。
end() N/A 结束当前命令块。
enrich()enrichRef() enrich 第10.1节“ Content Enricher”:将当前交换与从指定的生产者端点URI 请求的数据结合起来。
filter() filter 第8.2节“消息过滤器”:使用判断表达式过滤传入的交换。
idempotentConsumer() idempotentConsumer 第11.8节“幂等的使用者”:实现了一种策略来禁止重复消息。
inheritErrorHandler() @inheritErrorHandler 布尔选项,可用于禁用特定路由节点上的继承的错误处理程序(在Java DSL中定义为子条款,在XML DSL中定义为属性)。
inOnly() inOnly 将当前交换的MEP设置为InOnly(如果没有自变量),或者将交换作为InOnly发送到指定的端点。
inOut() inOut 将当前交换的MEP设置为InOut(如果没有参数),或者将交换作为InOut发送到指定的端点。
loadBalance() loadBalance 第8.10节“负载均衡器”:在一组端点上实现负载均衡。
log() log 将消息记录到控制台。
loop() loop 第8.16节“循环”:反复将每次交换重新发送到路由的后半部分。
markRollbackOnly() @markRollbackOnly (事务)将当前事务标记为仅回滚(不引发异常)。在XML DSL中,此选项设置为rollback元素上的布尔属性。请参阅《 Apache Karaf交易指南》
markRollbackOnlyLast() @markRollbackOnlyLast (事务)如果先前已将一个或多个事务与该线程关联,然后挂起,则此命令将最新事务标记为仅回滚(不引发异常)。在XML DSL中,此选项设置为rollback元素上的布尔属性。请参阅《 Apache Karaf交易指南》
marshal() marshal 使用指定的数据格式转换为低级或二进制格式,以准备通过特定的传输协议进行发送。
multicast() multicast 第8.13节“多播”:将当前交换多播到多个目的地,每个目的地都获得自己的交换副本。
onCompletion() onCompletion 定义一个子路由(end()在Java DSL中以终止),该子路由在主路由完成后执行。另请参见第2.14节“ OnCompletion”
onException() onException 定义一个子路由(end()在Java DSL中由终止),该子路由在发生指定的异常时执行。通常在自己的行上定义(不在路线中)。
pipeline() pipeline 第5.4节“管道和过滤器”:将交换发送到一系列端点,其中一个端点的输出成为下一个端点的输入。另请参见第2.1节“管道处理”
policy() policy 将策略应用于当前路由(当前仅用于事务策略-请参阅Apache Karaf事务指南)
pollEnrich()pollEnrichRef() pollEnrich 第10.1节“ Content Enricher”:将当前交换与从指定使用者端点URI 轮询的数据结合在一起。
process()processRef process 在当前交换上执行自定义处理器。请参阅“自定义处理器”一节第三部分“高级骆驼编程”
recipientList() recipientList 第8.3节“收件人列表”:将交换发送到在运行时计算出的收件人列表(例如,基于标题的内容)。
removeHeader() removeHeader 从交易所的“ 入栈消息中删除指定的标头。
removeHeaders() removeHeaders 从交易所的“ 入栈”消息中删除与指定模式匹配的标题。该模式可以具有以下形式prefix\* :在这种情况下,它与以前缀开头的每个名称匹配—否则,它将被解释为正则表达式。
removeProperty() removeProperty 从交易所中删除指定的交易所属性。
removeProperties() removeProperties 从交换中删除与指定模式匹配的属性。以逗号分隔的1个或多个字符串列表作为参数。第一个字符串是模式(请参见removeHeaders()上文)。后续字符串指定异常-这些属性保留。
resequence() resequence 第8.6节“重新排序器”:根据指定的Comparotor操作对传入的交换重新排序。支持批处理模式和模式。
rollback() rollback (事务)将当前事务标记为仅回滚(默认情况下也会引发异常)。请参阅《 Apache Karaf交易指南》
routingSlip() routingSlip 第8.7节“路由清单:基于从清单头中提取的端点URI的列表,通过动态构建的管道路由交换。
sample() sample 创建采样调节器,使您可以从路线上的流量中提取交流的样本。
setBody() setBody 设置交易所的“ 入栈”消息的消息正文。
setExchangePattern() setExchangePattern 将当前交换机的MEP设置为指定值。请参阅“消息交换模式”一节
setHeader() setHeader 设置交易所的入栈消息中的指定标头。
setOutHeader() setOutHeader 在交易所的出栈消息中设置指定的标头。
setProperty() setProperty() 设置指定的交换属性。
sort() sort In消息主体(可以选择在其中指定自定义比较器)的内容进行排序。
split() split 第8.4节“拆分器”:将当前交换拆分为一系列交换,其中每个拆分交换都包含原始消息正文的一个片段。
stop() stop 停止路由当前交换并将其标记为已完成。
threads() threads 创建线程池以同时处理路由的后半部分。
throttle() throttle 第8.8节“节流阀”:将流量限制为指定的水平(每秒变化)。
throwException() throwException 抛出指定的Java异常。
to() to 将交换发送到一个或多个端点。请参见第2.1节“管道处理”
toF() 不适用 使用字符串格式将交换发送到端点。也就是说,端点URI字符串可以以C printf()函数的样式嵌入替换。
transacted() transacted 创建一个Spring事务作用域,该作用域包围路由的后半部分。请参阅《Apache Karaf交易指南》
transform() transform 第5.6节“消息转换器”:将入栈消息头复制到出栈消息头,并将出栈消息主体设置为指定值。
unmarshal() unmarshal 使用指定的数据格式 将入栈消息主体从低级或二进制格式转换为高级格式。
validate() validate 采取判断表达式以测试当前消息是否有效。如果判断返回false,则抛出PredicateValidationException异常。
wireTap() wireTap 第12.3节“电线接头”:使用ExchangePattern.InOnlyMEP 将当前交换的副本发送到指定的电线接头URI 。

示例

要了解如何在路由中使用处理器,请参见以下示例:

Choice

所述choice()处理器是用于路由传入消息到替代端点生产条件语句。每个替代生产者端点之前都有一个when()方法,该方法采用判断参数。如果判断为true,则选择以下目标,否则处理将继续进行到when()规则中的下一个方法。例如,以下choice()处理器根据Predicate1Predicate2的值将传入消息定向到Target1Target2Target3

from("SourceURL")
    .choice()
        .when(Predicate1).to("Target1")
        .when(Predicate2).to("Target2")
        .otherwise().to("Target3");

或等效地在Spring XML中:

<camelContext id="buildSimpleRouteWithChoice" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURL"/>
    <choice>
      <when>
        <!-- First predicate -->
        <simple>header.foo = 'bar'</simple>
        <to uri="Target1"/>
      </when>
      <when>
        <!-- Second predicate -->
        <simple>header.foo = 'manchu'</simple>
        <to uri="Target2"/>
      </when>
      <otherwise>
        <to uri="Target3"/>
      </otherwise>
    </choice>
  </route>
</camelContext>

在Java DSL中,有一种特殊情况,您可能需要使用该endChoice()命令。一些标准的Apache Camel处理器使您可以使用特殊的子句来指定额外的参数,从而有效地打开通常由end()命令终止的额外级别的嵌套。例如,您可以将负载均衡器子句指定为loadBalance().roundRobin().to("mock:foo").to("mock:bar").end(),以在mock:foomock:bar端点之间负载均衡消息。但是,如果负载均衡器子句嵌入在选择条件中,则必须使用以下endChoice()命令终止该子句:

from("direct:start")
    .choice()
        .when(bodyAs(String.class).contains("Camel"))
            .loadBalance().roundRobin().to("mock:foo").to("mock:bar").endChoice()
        .otherwise()
            .to("mock:result");

Filter

所述filter()处理器可以被用来防止到达生产者端点无趣消息。它只有一个判断参数:如果判断为true,则允许消息交换到达生产者;如果判断为假,则消息交换被阻止。例如,以下过滤器阻止消息交换,除非传入消息包含标头foo,其值等于bar

from("SourceURL").filter(header("foo").isEqualTo("bar")).to("TargetURL");

或等效地在Spring XML中:

<camelContext id="filterRoute" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURL"/>
    <filter>
      <simple>header.foo = 'bar'</simple>
      <to uri="TargetURL"/>
    </filter>
  </route>
</camelContext>

Throttle

throttle()处理器保证了生产的端点不会过载。节流器通过限制每秒可以通过的消息数来工作。如果传入消息超过指定的速率,则调节器将多余的消息累积在缓冲区中,然后将它们更慢地传输到生产者端点。例如,要将吞吐量速率限制为每秒100条消息,可以定义以下规则:

from("SourceURL").throttle(100).to("TargetURL");

或等效地在Spring XML中:

<camelContext id="throttleRoute" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURL"/>
    <throttle maximumRequestsPerPeriod="100" timePeriodMillis="1000">
      <to uri="TargetURL"/>
    </throttle>
  </route>
</camelContext>

自定义处理器

如果此处描述的标准处理器都不提供所需的功能,则始终可以定义自己的自定义处理器。要创建自定义处理器,请定义一个实现org.apache.camel.Processor接口并覆盖该process()方法的类。以下定制处理器从传入消息中MyProcessor删除命名的标头foo

示例1.3 实施自定义处理器类

public class MyProcessor implements org.apache.camel.Processor {
public void process(org.apache.camel.Exchange exchange) {
  inMessage = exchange.getIn();
  if (inMessage != null) {
      inMessage.removeHeader("foo");
  }
}
};

要将自定义处理器插入路由器规则,请调用process()方法,该方法提供了将处理器插入规则的通用机制。例如,以下规则调用示例1.3“实现自定义处理器类”中定义的处理器

org.apache.camel.Processor myProc = new MyProcessor();

from("SourceURL").process(myProc).to("TargetURL");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容