这篇文章取自《Open Source ESBs in Action: Example Implementations in Mule and ServiceMix》一书。这部分内容展示了如何通过邮件服务器集成 Mule 和 ServiceMix。
在性能和速度无关紧要的情况下,有一种非常容易且具有异步性的应用集成方式:基于邮件的集成。使用 POP3 和 SMTP 可以简化应用之间的通信。除此之外,它还简化了跟终端用户或者具体事件的支持部门之间所进行的通信。例如,当错误发生时,通过发送包含错误及附加信息的邮件自动通知支持部门。
我们将展示如何从 Mule 和 ServcieMix 使用 SMTP 和 POP3 协议跟邮件服务器通信。至于邮件服务器,我们将使用 Apache James,它是一个支持所有邮件相关协议的开源邮件服务器。当然,就本节的例子而言,你也可以使用自己的邮件服务器。
我们会再次关注连通性的功能,并在此向你展示两个基本示例。第一个示例如图 6.1,它将展示如何从 Mule 和 ServiceMix 给邮件服务器发送电子邮件。
图 6.1,在本例中,我们将使用 ESB 从文件系统中读取文件,并使用 SMTP 连通性把该消息转发给邮件服务器。
我们使用 Mule 和 ServiceMix 实现的另一个示例如图 6.2,从邮件服务器接收电子邮件消息。
图 6.2,在本例中,我们将使用具有 POP3 连通性的 ESB 从邮件服务器接收电子邮件,并把该电子邮件消息发送给文件系统。
为了实现图 6.1 和 6.2 的示例,我们将使用文件连通性来触发或处理邮件连通性的结果,因为这样容易测试。这些图也显示了邮件客户端的使用,并且在这些示例中,你可以使用你喜爱的邮件客户端。首先让我们看看如何在 Mule 中配置 SMTP 连通性。
将 Mule 连接到 POP3 和 SMTP
我们将着手的第一件事情就是如何对 Mule 进行设置,以便我们能够把电子邮件发送到 Mule 配置中指定的电子邮件地址。我们已在本节的介绍中说过,我们打算从文件系统中读取一个文件,并把这个文件的内容作为电子邮件消息体发送到一个指定电子邮件地址。在如下代码清单中显示的 Mule 配置定义了这个 SMTP 连通性。
清单 6.1 Mule 服务配置:使用 SMTP 发送电子邮件
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.0" xmlns:file="http://www.mulesource.org/schema/mule/file/2.0" xmlns:smtp="http://www.mulesource.org/schema/mule/smtp/2.0"> <model name="mail-model"> <service name="file-to-mail"> <inbound> <file:inbound-endpoint path="chapter6/4a/in"> #1 <file:file-to-string-transformer /> </file:inbound-endpoint> </inbound> <outbound> <outbound-pass-through-router> <smtp:outbound-endpoint #2 to="johndoe@localhost" cc="info@localhost" from="mu le@localhost" replyT o="sales@localhost" subject="You've got mail from Mule!" host="localhost" #3 port="10025" #3 user="mule" #3 password="mule" /> #3 </outbound-pass-through-router> </outbound> </service> </model> </mule> <b>#1: 文件输入路径 <br></br>#2: 定义 SMTP 发送端点 <br></br>#3: 配置 SMTP 连接属性 </b>
我们只需要在 SMTP 发送端点定义 (#2) 中告诉 Mule 连接 SMTP 服务器的方式 (#3)。在这个例子中,我们使用“mule”作为连接本地邮件服务器(Apache James)的用户名和密码。
在使用这个 Mule 配置启动 Mule 之前,我们首先需要使用 ch6-build.xml 文件中的 Ant target:ext:start-james 来启动 Apache James。现在我们可以使用同一 Ant 构建文件中的 Ant target:chapter6-mail-smtp-4a 来运行这个示例。为了触发代码清单 6.26 中的 SMTP 服务定义,你需要在 chapter6/4a/in 目录中放入一个文件 (#1)。Mule 会把文件内容(文件内容作为电子邮件的消息体)发送到指定端点。我们现在可以使用任何邮件客户端接收这条消息了,如下图:
图 6.3 截屏显示了通过我们已经实现的 Mule 配置,能够接收电子邮件消息。
我们已经看到了如何配置 Mule 去发送 E-Mail,那么现在让我们看看这一节的另一个内容:接收电子邮件消息。为了演示这个示例,我们将使用邮件客户端发送邮件,并使用 Mule POP3 传输(Transport)读取来自邮件服务器的消息。首先,我们将再次看看 Mule 配置,如代码清单 6.2。
清单 6.2 Mule 服务配置:使用 POP3 接收电子邮件。
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.0" xmlns:file="http://www.mulesource.org/schema/mule/file/2.0" xmlns:pop3="http://www.mulesource.org/schema/mule/pop3/2.0"> <pop3:connector name="pop3Connector" checkFrequency="5000" #1 deleteReadMessages="false"/> #2 <model name="mail-model"> <service name="mail-sender"> <inbound> <pop3:inbound-endpoint #3 host="localhost" name="mule" password="mule" port="10110" /> </inbound> <outbound> <outbound-pass-through-router> <file:outbound-endpoint path="chapter6/4b/out"/> #4 </outbound-pass-through-router> </outbound> </service> </model> </mule> <b>#1: 每隔 5 秒钟检查一次电子邮件 <br></br>#2: 不删除已读电子邮件 <br></br>#3: POP3 连接配置 <br></br>#4: 文件输出路径 </b>
上述代码看起来和列表 6.1 中的代码类似,在 6.1 中我们讨论了如何发送电子邮件消息。我们配置了 POP3 服务器的位置和用来创建连接的用户名和密码 (#3). 我们还指定了 pop3:connector 上某些其它属性。在这个例子中,我们告诉 Mule 不要删除已被它接收的消息 (#2),并且每隔 5 秒检查一次新的电子邮件消息 (#1)。
要想对此进行测试,使用简单的邮件客户端即可。只需向 mule@localhost 发送一条消息,你就会看到 Mule 将获得这条消息并对它进行处理。
至此,我们已经知道了 Mule 如何跟 POP3 和 SMTP 一起工作。除了这些协议,Mule 还支持其安全变种:SPOP3、SMTPS 和 IMAP。使用这些安全传输的方式和本节中所讲的方式是一样的,你仅仅需要提供额外的安全属性,如证书。
将 ServiceMix 连接到 POP3 和 SMTP
为了在 ServiceMix 上实现邮件连通性,我们需要一个使用 POP3 接收电子邮件消息的绑定组件,还需要一个使用 SMTP 发送电子邮件消息的绑定组件。ServiceMix 有一个可用的邮件绑定组件,但只在 3.3 或者更高版本上才提供。在撰写本书的时候,该版本尚未发布,因此我们将使用由另一个 JBI 实现提供的邮件 JBI 组件。
在 JDBC 示例中,我们已经展示了如何在 OpenESB 项目中使用 JBI 组件。在本例中,我们将使用 Petals 项目提供的 JBI 组件,该项目已经在第 1 章讨论过了。当我们在第 3 章创建环境的时候,我们已经提供了这个绑定组件,所以这里就不需要额外的安装或者下载。
SERVICEMIX 中的 PETALS 组件 遗憾的是,在 ServiceMix 容器中,Petals 组件并不是开箱即用的。之前我们就提到,这通常是由不兼容的 Jar 文件或其他库以及类加载问题所引起的。然而在这个例子中,这一问题是由 ServiceMix 的一个 bug 所引起的。只要检查一下 JDBC 示例中的 jbi.xml 文件,你就能发现我们指定了 consume 和 provide 元素。JBI 规范对这两个元素进行了描述,它们不允许使用特定于服务的配置。ServiceMix 使用 xbeans 完成这一配置,而 OpenESB 项目则使用 WSDL 文件配置服务。但是,Petals 使用了 JBI 规范中描述的标准扩展机制。这允许额外的配置元素出现在 jbi.xml 文件中。但在 ServiceMix 中,只有第一个扩展元素能够被处理。我们已经提供了解决这个问题的补丁。
我们在本节一开始就已经说过,我们要从文件系统中读取一个文件,然后使用 ServiceMix 把包含文件内容的电子邮件消息发送到某个电子邮件地址。
到目前为止,我们在每个示例中所做的第一件事就是配置一个轮询文件系统的简单文件轮询器。该配置如代码清单 6.3 所示。
清单 6.3 文件轮询器配置:向邮件服务发送消息
<beans> <file:poller service="esb:filePoller" endpoint="simpleToMailPoller" targetService="esb:mail-service" #1 targetEndpoint="mailEndpoint" #1 file="chapter6/6a-mail/in" #2 period="2000"> </file:poller> </beans> <b>#1: 待调用的邮件服务 <br></br>#2: 待轮询的目录 </b>
在这个文件轮询器配置中,我们仅仅从文件系统读取文件,然后把收到的文件发送给邮件服务端点。现在让我们把重点放在邮件服务配置上。
我们在前一节就已经解释了,ServiceMix 中服务单元的配置是以 xbean.xml 文件形式完成的。当联合使用 Petals 的时候,你是在 jbi.xml 文件中而不是在 xbean.xml 文件中配置服务单元。向邮件地址发送消息的 Petals 服务单元的配置如清单 6.4 所示。
清单 6.4 使用 Petals 邮件绑定组件发送邮件的配置:
<?xml version="1.0" encoding="UTF-8"?> <jbi:jbi xmlns:xsi="http://www.w3.org/2001/XMLSchem a-instance" xmlns:petals="http://petals.ow2.org/extensions" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:esb="http://opensourceesb/mail/" version="1.0"> <jbi:services binding-component="true"> <jbi:provides interface-name="esb:MailInterface" #1 service-name="esb:MailService" endpoint-name="mailEndpoint"> <petals:wsdl></petals:wsdl> <petals:su-interceptors></petals:su-interceptors> <petals:params> <petals:param name="scheme">smtp</petals:param> <petals:param name="hostname">localhost</petals:param> #2 <petals:param name="port">10025</petals:param> #2 <petals:param name="username">petals</petals:param> #2 <petals:param name="password">petals</petals:param> #2 <petals:param name="from"> servicemix@localhost </petals:param> <petals:param name="to">sm@localhost</petals:param> #3 </petals:params> </jbi:provides> </jbi:services> </jbi:jbi> <b>#1: JBI 服务定义 <br></br>#2: 邮件连接定义 <br></br>#3: 目标电子邮件地址 </b>
给 ServiceMix 添加支持邮件的 Petals 邮件绑定组件很简单。你所要做的就是配置邮件服务器的位置 (#2)。有一件事情你可能已经注意到了:我们没有设置邮件主题。这是 Petals 邮件组件的一个局限,待发送邮件消息的主题通常被设置成服务的名字。所以在这个示例中,发送邮件的地方,邮件的主题就是“mail-service”。该组件目前的一项工作就是提供主题名的可配置性。
关于这个配置,还需要注意的一件事是“provides”元素 (#1)。在第 2 章中,我们已经讨论了消费者和提供者。这个例子实现了一个提供者,其他 JBI 服务可通过向这个服务端点发送一条 JBI 消息,从而对该提供者进行访问。
如果我们现在用 Ant 构建文件(ch6-build.xml)运行这个例子,往清单 6.2 中指定的输入目录中放入一个文件,ServiceMix 就会取出这条消息并把它发送给 Petals 邮件组件,然后该组件就会将一条电子邮件消息发送给已配置的邮件地址:sm@localhost(#3)。
为了接收电子邮件消息,我们需要为同一个 Petals 邮件绑定组件配置另一个 jbi.xml 文件,只是这次我们需要消费一个由 ServiceMix 文件绑定组件提供的服务端点。首先让我们看看由如下代码片断中的文件组件所提供的服务端点。
<file:sender service="esb:mailFileWriter" endpoint="sender" directory="chapter6/6-mail/out"> </file:sender>
这个文件绑定组件的配置提供了一个名为 esb:mail-service 的 JBI 服务,并拥有一个名为 sender 的端点。我们将从代码清单 6.5 所示的 Petals 邮件配置中消费这个服务端点。
清单 6.5 邮件组件的 Petals 配置:接收电子邮件。
<?xml version="1.0" encoding="UTF-8"?> <jbi:jbi xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:petals="http://petals.ow2.org/extensions" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:esb="http://opensourceesb/mail/" version="1.0"> <jbi:services binding-component="true"> <jbi:consumes #1 interface-name="esb:mailFileWriterInterface" service-name="esb:mailFileWriter" endpoint-name="sender"> <petals:mep>InOnly</petals:mep> <petals:operation>sendMessage</petals:operation> <petals:params> <petals:param name="period">10000</petal s:param> <petals:param name="scheme">pop3</petals:param> <petals:param name="hostname"> #2 localhost </petals:param> <petals:param name="port">10110</petals:param> <petals:param name="username"> #3 servicemix </petals:param> <petals:param name="password"> servicemix </petals:param> </petals:params> </jbi:consumes> </jbi:services> </jbi:jbi> <b>#1: JBI 服务定义 <br></br>#2: 邮件主机名的配置 <br></br>#3: 邮件服务器认证所用的用户名 </b>
其与代码清单 6.4 的邮件组件配置最大的区别在于,对于 scheme,我们指定的是 POP3 ,而不是 SMTP。这将告诉 Petals 邮件组件开始对邮件消息进行轮询。每当一条消息被收到,它都会被发送给“consume”元素的服务端点 (#1)。在这个示例中,我们指定了文件发送者 JBI 服务的服务和端点名。因此,只要收到一条消息,它都会被传递给文件发送者 JBI 服务,它负责把消息写入文件系统。
除了 Petals,OpenESB 也提供了邮件组件。OpenESB 的邮件组件提供了大量配置选项和特性,但由于需要基于 WSDL 的配置(参见 6.3 节的 JDBC 例子),它的使用难度较大。如果你只想用一种容易方式连接到邮件服务器,Petals 组件可能是最好的解决方案;但若你需要更多的高级特性且不介意使用基于 WSDL 的配置,那么 OpenESB 组件会是一个不错的选择。当然,ServiceMix 3.3 版本将提供一个开箱即用的邮件绑定组件。
查看英文原文: Application Integration Through Mail Servers 。
给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论