在性能和速度無關(guān)緊要的情況下,有一種非常容易且具有異步性的應用集成方式:基于郵件的集成。使用POP3和SMTP可以簡化應用之間的通信。除此之外,它還簡化了跟終端用戶或者具體事件的支持部門之間所進行的通信。例如,當錯誤發(fā)生時,通過發(fā)送包含錯誤及附加信息的郵件自動通知支持部門。
我們將展示如何從Mule和ServcieMix使用SMTP和POP3協(xié)議跟郵件服務器通信。至于郵件服務器,我們將使用Apache James,它是一個支持所有郵件相關(guān)協(xié)議的開源郵件服務器。當然,就本節(jié)的例子而言,你也可以使用自己的郵件服務器。
我們會再次關(guān)注連通性的功能,并在此向你展示兩個基本示例。第一個示例如圖6.1,它將展示如何從Mule和ServiceMix給郵件服務器發(fā)送電子郵件。
圖6.1,在本例中,我們將使用ESB從文件系統(tǒng)中讀取文件,并使用SMTP連通性把該消息轉(zhuǎn)發(fā)給郵件服務器。
我們使用Mule和ServiceMix實現(xiàn)的另一個示例如圖6.2,從郵件服務器接收電子郵件消息。
圖6.2,在本例中,我們將使用具有POP3連通性的ESB從郵件服務器接收電子郵件,并把該電子郵件消息發(fā)送給文件系統(tǒng)。
為了實現(xiàn)圖6.1和6.2的示例,我們將使用文件連通性來觸發(fā)或處理郵件連通性的結(jié)果,因為這樣容易測試。這些圖也顯示了郵件客戶端的使用,并且在這些示例中,你可以使用你喜愛的郵件客戶端。首先讓我們看看如何在Mule中配置SMTP連通性。
我們將著手的第一件事情就是如何對Mule進行設置,以便我們能夠把電子郵件發(fā)送到Mule配置中指定的電子郵件地址。我們已在本節(jié)的介紹中說過,我們打算從文件系統(tǒng)中讀取一個文件,并把這個文件的內(nèi)容作為電子郵件消息體發(fā)送到一個指定電子郵件地址。在如下代碼清單中顯示的Mule配置定義了這個SMTP 連通性。
清單6.1 Mule服務配置:使用SMTP發(fā)送電子郵件
<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 #2to="johndoe@localhost"cc="info@localhost"from="mu le@localhost"replyT o="sales@localhost"subject="You've got mail from Mule!"host="localhost" #3port="10025" #3user="mule" #3password="mule" /> #3</outbound-pass-through-router></outbound></service></model></mule>#1: 文件輸入路徑
#2: 定義SMTP發(fā)送端點
#3: 配置SMTP連接屬性
我們只需要在SMTP發(fā)送端點定義(#2)中告訴Mule連接SMTP服務器的方式(#3)。在這個例子中,我們使用“mule”作為連接本地郵件服務器(Apache James)的用戶名和密碼。
在使用這個Mule配置啟動Mule之前,我們首先需要使用ch6-build.xml文件中的Ant target:ext:start-james來啟動Apache James?,F(xiàn)在我們可以使用同一Ant構(gòu)建文件中的Ant target:chapter6-mail-smtp-4a來運行這個示例。為了觸發(fā)代碼清單6.26中的SMTP服務定義,你需要在 chapter6/4a/in目錄中放入一個文件(#1)。Mule會把文件內(nèi)容(文件內(nèi)容作為電子郵件的消息體)發(fā)送到指定端點。我們現(xiàn)在可以使用任何郵件客戶端接收這條消息了,如下圖:
圖6.3 截屏顯示了通過我們已經(jīng)實現(xiàn)的Mule配置,能夠接收電子郵件消息。
我們已經(jīng)看到了如何配置Mule去發(fā)送E-Mail,那么現(xiàn)在讓我們看看這一節(jié)的另一個內(nèi)容:接收電子郵件消息。為了演示這個示例,我們將使用郵件客戶端發(fā)送郵件,并使用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" #1deleteReadMessages="false"/> #2<model name="mail-model"><service name="mail-sender"><inbound><pop3:inbound-endpoint #3host="localhost"name="mule"password="mule"port="10110" /></inbound><outbound><outbound-pass-through-router><file:outbound-endpointpath="chapter6/4b/out"/> #4</outbound-pass-through-router></outbound></service></model></mule>#1: 每隔5秒鐘檢查一次電子郵件
#2: 不刪除已讀電子郵件
#3: POP3連接配置
#4: 文件輸出路徑
上述代碼看起來和列表6.1中的代碼類似,在6.1中我們討論了如何發(fā)送電子郵件消息。我們配置了POP3服務器的位置和用來創(chuàng)建連接的用戶名和密碼 (#3). 我們還指定了pop3:connector上某些其它屬性。在這個例子中,我們告訴Mule不要刪除已被它接收的消息(#2),并且每隔5秒檢查一次新的電子郵件消息(#1)。
要想對此進行測試,使用簡單的郵件客戶端即可。只需向mule@localhost發(fā)送一條消息,你就會看到Mule將獲得這條消息并對它進行處理。
至此,我們已經(jīng)知道了Mule如何跟POP3和SMTP一起工作。除了這些協(xié)議,Mule還支持其安全變種:SPOP3、SMTPS和IMAP。使用這些安全傳輸?shù)姆绞胶捅竟?jié)中所講的方式是一樣的,你僅僅需要提供額外的安全屬性,如證書。
為了在ServiceMix上實現(xiàn)郵件連通性,我們需要一個使用POP3接收電子郵件消息的綁定組件,還需要一個使用SMTP發(fā)送電子郵件消息的綁定組件。ServiceMix有一個可用的郵件綁定組件,但只在3.3或者更高版本上才提供。在撰寫本書的時候,該版本尚未發(fā)布,因此我們將使用由另一個 JBI實現(xiàn)提供的郵件JBI組件。
在JDBC示例中,我們已經(jīng)展示了如何在OpenESB項目中使用JBI組件。在本例中,我們將使用Petals項目提供的JBI組件,該項目已經(jīng)在第1章討論過了。當我們在第3章創(chuàng)建環(huán)境的時候,我們已經(jīng)提供了這個綁定組件,所以這里就不需要額外的安裝或者下載。
SERVICEMIX中的PETALS組件
遺憾的是,在ServiceMix容器中,Petals組件并不是開箱即用的。之前我們就提到,這通常是由不兼容的Jar文件或其他庫以及類加載問題所引起的。然而在這個例子中,這一問題是由ServiceMix的一個bug所引起的。只要檢查一下JDBC示例中的jbi.xml文件,你就能發(fā)現(xiàn)我們指定了consume和provide元素。JBI規(guī)范對這兩個元素進行了描述,它們不允許使用特定于服務的配置。ServiceMix使用xbeans完成這一配置,而OpenESB項目則使用WSDL文件配置服務。但是,Petals使用了JBI規(guī)范中描述的標準擴展機制。這允許額外的配置元素出現(xiàn)在 jbi.xml文件中。但在ServiceMix中,只有第一個擴展元素能夠被處理。我們已經(jīng)提供了解決這個問題的補丁。
我們在本節(jié)一開始就已經(jīng)說過,我們要從文件系統(tǒng)中讀取一個文件,然后使用ServiceMix把包含文件內(nèi)容的電子郵件消息發(fā)送到某個電子郵件地址。
到目前為止,我們在每個示例中所做的第一件事就是配置一個輪詢文件系統(tǒng)的簡單文件輪詢器。該配置如代碼清單6.3所示。
清單6.3 文件輪詢器配置:向郵件服務發(fā)送消息
<beans><file:poller service="esb:filePoller"endpoint="simpleToMailPoller"targetService="esb:mail-service" #1targetEndpoint="mailEndpoint" #1file="chapter6/6a-mail/in" #2period="2000"></file:poller></beans>#1: 待調(diào)用的郵件服務
#2: 待輪詢的目錄
在這個文件輪詢器配置中,我們僅僅從文件系統(tǒng)讀取文件,然后把收到的文件發(fā)送給郵件服務端點?,F(xiàn)在讓我們把重點放在郵件服務配置上。
我們在前一節(jié)就已經(jīng)解釋了,ServiceMix中服務單元的配置是以xbean.xml文件形式完成的。當聯(lián)合使用Petals的時候,你是在 jbi.xml文件中而不是在xbean.xml文件中配置服務單元。向郵件地址發(fā)送消息的Petals服務單元的配置如清單6.4所示。
清單6.4 使用Petals郵件綁定組件發(fā)送郵件的配置:
<?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" #1service-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>#1: JBI服務定義
#2: 郵件連接定義
#3: 目標電子郵件地址
給ServiceMix添加支持郵件的Petals郵件綁定組件很簡單。你所要做的就是配置郵件服務器的位置(#2)。有一件事情你可能已經(jīng)注意到了:我們沒有設置郵件主題。這是Petals郵件組件的一個局限,待發(fā)送郵件消息的主題通常被設置成服務的名字。所以在這個示例中,發(fā)送郵件的地方,郵件的主題就是“mail-service”。該組件目前的一項工作就是提供主題名的可配置性。
關(guān)于這個配置,還需要注意的一件事是“provides”元素(#1)。在第2章中,我們已經(jīng)討論了消費者和提供者。這個例子實現(xiàn)了一個提供者,其他JBI服務可通過向這個服務端點發(fā)送一條JBI消息,從而對該提供者進行訪問。
如果我們現(xiàn)在用Ant構(gòu)建文件(ch6-build.xml)運行這個例子,往清單6.2中指定的輸入目錄中放入一個文件,ServiceMix就會取出這條消息并把它發(fā)送給Petals郵件組件,然后該組件就會將一條電子郵件消息發(fā)送給已配置的郵件地址: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 #1interface-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"> #2localhost</petals:param><petals:param name="port">10110</petals:param><petals:param name="username"> #3servicemix</petals:param><petals:param name="password">servicemix</petals:param></petals:params></jbi:consumes></jbi:services></jbi:jbi>#1: JBI 服務定義
#2: 郵件主機名的配置
#3: 郵件服務器認證所用的用戶名
其與代碼清單6.4的郵件組件配置最大的區(qū)別在于,對于scheme,我們指定的是POP3 ,而不是SMTP。這將告訴Petals郵件組件開始對郵件消息進行輪詢。每當一條消息被收到,它都會被發(fā)送給“consume”元素的服務端點 (#1)。在這個示例中,我們指定了文件發(fā)送者JBI服務的服務和端點名。因此,只要收到一條消息,它都會被傳遞給文件發(fā)送者JBI服務,它負責把消息寫入文件系統(tǒng)。
除了Petals,OpenESB也提供了郵件組件。OpenESB的郵件組件提供了大量配置選項和特性,但由于需要基于WSDL的配置(參見6.3節(jié)的 JDBC例子),它的使用難度較大。如果你只想用一種容易方式連接到郵件服務器,Petals組件可能是最好的解決方案;但若你需要更多的高級特性且不介意使用基于WSDL的配置,那么OpenESB組件會是一個不錯的選擇。當然,ServiceMix 3.3版本將提供一個開箱即用的郵件綁定組件。