This article is taken from the book Open Source ESBs in Action: Example Implementations in Mule and ServiceMix. This segment shows how to integrate Mule and ServiceMix with a mail server.
A very easy and asynchronous way to integrate applications where performance and speed aren't an issue is a Mail based integration approach. Using POP3 and SMTP allows for easy communication between applications. Besides that it can serve as an easy way to communicate with the end user or the support department about certain events. For instance when an error occurs the support department can be automatically notified by sending an email containing the error message and some additional information.
We will show how to use the SMTP and POP3 protocols from Mule and ServiceMix to communicate with a Mail server. For the Mail server we will be using Apache James, which is an Open Source Mail server that supports all Mail related pr otocols. You could of course also use your own Mail server for the examples in this section.
We will once again focus on the connectivity functionality and only show you a couple of basic examples. The first example as shown in figur e 6.8, will show how to send an e-mail message to a Mail Server from Mule and ServiceMix.
Figure 6.1 Example where we read a file from the file system with the ESB and forward the message to a Mail server using SMTP connectivity.
The other example we will implement with Mule and ServiceMix is how to receive e-mail messages from a Mail server as shown in figure 6.9.
Figure 6.2 Example where we receive an e-mail from a Mail server using the ESB with POP3 connectivity and sent the e-mail message to the file system.
To implement examples as shown in figure 6.8 and 6.9 we will use file connectivity to trigger or process the result of the Mail connectivity, because this is easy to test. The figures also show the use of a Mail client, a nd you can use your favorite Mail client to work with these examples. Let's first look at how we to configure SMTP connectivity in Mule.
Connecting Mule to POP3 and SMTP
The first thing we're going to look at is how to setup Mule so that we can send an email to a specific e-mail address from a Mule configuration. As we've mentioned in the introduction of this section, we're going to read a file from the file system and send the file contents as the body an e-mail to a configured email address. The Mule configuration shown in code listing defines this SMTP connectivity.
Listing 6.1 Mule services configuration which sends mails using 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> #1: The file input directory
#2: Define a SMTP outbound endpoint
#3: Configure SMTP connection properties
We only need to tell mule how to connect to the SMTP server (#3), as part of a SMTP outbound endpoint definition (#2). In this case we’ll connect to a local Mail server (Apache James) using mule for the username and password.
Before we can start-up Mule with this Mule configuration, we first need to start Apache James with the ext:start-james Ant target in the ch6-build.xml file. We can now run this example with the chapter6-mail-smtp-4a Ant target in the same Ant build file. To trigger the SMTP service definition of code listing 6.26 you need to drop a file into the chapter6/4a/in directory (#1). Mule will send the file content to the configured endpoint, with the content of the file as the body of the e-mail message. We can now use any Mail client to receive the message as shown figure
Figure 6.3 Screenshot showing that we can receive an e-mail message with the Mule configuration we’ve implemented.
We've seen how to configure Mule to send e-mails, so now let's look at the next part of this section, which is receiving e-mail messages. To work with this example we will use an Mail client to send a message, and use the Mule POP3 transport to read the message from the Mail server. We'll start again by looking at the Mule configuration shown in code listing 6.27.
Listing 6.2 Mule service configuration which receives e-mails using 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> #1: E-mail check every 5 seconds
#2: Don't delete read e-mails
#3: POP3 connection configuration
#4: File output directory
This code looks very similar to the Mule configuration of code listing 6.26, where we discussed how to send e-mail messages. We configure where the POP3 server is located and which username and password should be used to make the connection (#3). We have also specified some additional properties on the pop3:connector. In this case we tell Mule to not delete messages it has received (#2), and to check every five seconds for new e-mail messages (#1).
If we want to test this we can use a simple Mail client. Just send a message to mule@localhost and you'll see that Mule will pick it up and process it.
We've now seen how Mule can work with POP3 and SMTP. Besides these protocols Mule also supports the secure variants: SPOP3 and SMTPS and also IMAP. You use these secure transports the same way as the ones mentioned in this section, you just have to supply some additional security properties such as certificates.
Connecting ServiceMix to POP3 and SMTP
To implement Mail connectivity with ServiceMix we will need a Binding Component to receive e-mail messages using POP3 and we need a Binding Component that is able to send e-mail messages using SMTP. There is a Mail Binding Component available for ServiceMix, but this BC is only available for version 3.3 and greater. This version is not yet released at the moment of writing, so we will use a Mail JBI component provided b y another JBI implementation.
In the JDBC example we’ve already shown how to use a JBI component from the OpenESB project. In this example we’ll be using a JBI component provided by the Petals project, which we already discussed in chapter 1. When you created the environment in chapter 3 we’ve already pr ovided this Binding Component, so no e xtra installs or downloads are needed.
PETALS COMPONENTS IN SERVICEMIX
The Petals components unfortunately don’t work out of the box in th e ServiceMix container. We mentioned earlier that usually this is caused by incompatible Jar files or other library and class loading issues. In this case how ever, the problems are simply caused by a bug in ServiceMix. If you look at the jbi.xml file from the JDBC example, you can see that we specify consumes and provides elements. These two elements are described in the JBI specification, but don’t allow service specific configuration. ServiceMix uses xbeans for thi s configuration, and the OpenESB project configures services uses a WSDL file. Howe ver, Petals use the standard extension mechanism which is described in the JBI specification. This allows additional configuration elements to be present in the jbi.xml file. In ServiceMix however only the first of these extension elements was processed. We’ve provided you with a patched version, to solve this issue.
As we’ve explained at the beginning of this section we want to read a file from the file system and use ServiceMix to send an e-mail message using the file contents to a certain e-mail address.
The first thing which we’ve done in every example so far is configure a simple file poller on the file system. This configuration is shown in listing 6.28.
Listing 6.3 File poller configuration which sends the message to the mail service.
<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> #1: The Mail service to invoke
#2: The directory to poll
In the file poller implementation we just read a file from the file system and send the received file to the Mail service endpoint. Now let’s focus on the Mail service implementation.
We’ve explained in previous sections that configuring Service Units in ServiceMix is done in the form of xbean.xml files. When you’re working with Petals, you don’t configure the Service Unit in an xbean.xml file, you configure it in a jbi.xml file. The configuration of a Petals Service Unit which sends a message to an email address is shown in listing 6.29.
Listing 6.4 Configuration for sending mails using the Petals Mail Binding Component.
<?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> #1: JBI service definition
#2 : Mail connection definition
#3: Target e-mail address
Adding the Petals Mail Binding Com ponent for Mail support to ServiceMix is very easy. All you have to do is configure the location of the Mail server (#2). One thing you might notice is tha t we didn’t set the subject. This is a limitation of the Petals Mail component, the subject of the email message sent is always set to the name of service. So in this example where a e-mail message is sent, the subject will be mail-service. Work is currently being done on this component to make the subject name configurable.
One more thing to notice about this configuration is the “provides” element (#1). In chapter 2 we talked about consumers and providers. This example implements a provider, which can be accessed from other JBI services by sending a JIB message to this service endpoint.
If we now run this example with the ch6-build.xml Ant build file, and drop a file into the input directory which we specified in code listing 6.27, ServiceMix will pick up this message and send it to the Petals Mail component which will send an e-mail message to the configured email address, sm@localhost (#3).
To receive e-mail messages we need to configure another jbi.xml file for the same Petals Mail Binding Component, only this time we consume a service endpoint provided by the ServiceMix File Binding Component. Let’s first look at the service endpoint which is provided by the File component in the following code snippet.
<file:sender service="esb:mailFileWriter" endpoint="sender" directory="chapter6/6-mail/out"> </file:sender>
This File Binding Component configuration provides a JBI service with the name esb:mail-service and has an endpoint with the name sender. We will consume this service endpoint from our Petals Mail configuration as shown in code listing 6.30.
Listing 6.5 Petals configuration for the Mail component to receive e-mails.
<?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> #1: JBI service definition
#2: Mail hostname configuration
#3: Username for Mail server authentication
The main difference with the Mail component configuration of code listing 6.29 is that we specify a scheme of POP3 instead of SMTP. This will tell the Petals Mail component to start polling for mail messages. Whenever a message is received it will be sent to the service endpoint configured in the consume section (#1). In this example we specified the service and endpoint names for the File sender JBI service. So whenever a message is received it will be passed on to the File sender JBI service which writes it to the file sytem.
Besides Petals, OpenESB also provides a Mail component. The OpenESB Mail component provides a lot of configuration options and has a lot of features but is somewhat harder to use since it requires the WSDL based configuration we saw in the JDBC example of section 6.3. If you just want an easy way to connect to Mail servers the Petals component is probably the best solution, if you however need more advanced features and don’t mind the WSDL based configuration the OpenESB component would a better choice. Of course, when ServiceMix version 3.3 will be released a Mail Binding Component will be available out-of-the-box.