Simple Mail Forwarding

This cookbook page shows how to implement a simple mail forwarder.

Situation

We want to poll mails from a mail box and forward them to another adress.

This is a very simple example showing how to route messages from a mail poller endpoint to a mail sender endpoint doing some content filtering.

Requirements

For this example we need 2 endpoints configured in ServiceMix.

  • a mail poller endpoint
  • a mail sender endpoint

You may put the mail poller and sender together into a single service unit. We divided them here for a better overview.

This recipe has been tested with servicemix-mail-2009.02-SNAPSHOT only.

The mail poller

The mail poller will poll a specific mail box for new messages and routes them to the mail sender service.

xbean.xml
<?xml version="1.0"?>
<beans xmlns:mail="http://servicemix.apache.org/mail/1.0"
       xmlns:ex="http://servicemix.apache.org/example"
       xmlns:sm="http://servicemix.apache.org/config/1.0">

  <mail:poller service="ex:mailPoller"
               endpoint="pollerEndpoint"
               targetService="ex:mailSender"
               period="30000"
               connection="imap://lhein@testserver:143/INBOX?password=myPass"
               deleteProcessedMessages="false"
               processOnlyUnseenMessages="true" />

</beans>

The above definition will create a mail poller endpoint which polls the mail box every 30 seconds not deleting the polled messages but marking them as seen. This poller will only process unseen messages. Alternatively you could switch deleteProcessedMessages to true and skip the processOnlyUnseenMessages. That would delete the polled message from the mail box on successfully sending the mail to the mail sender endpoint. We are using an IMAP server here but you can also put in a POP3 account. The targetService points to the mail sender endpoint.

The mail sender

The mail sender will send the received messages to a given email adress.

xbean.xml
<?xml version="1.0"?>
<beans xmlns:mail="http://servicemix.apache.org/mail/1.0"
       xmlns:ex="http://servicemix.apache.org/example"
       xmlns:sm="http://servicemix.apache.org/config/1.0">

 <mail:sender service="ex:mailSender" 
              endpoint="senderEndpoint"
              receiver="[email protected]"
              connection="smtp://lhein@testserver?password=myPass" >

     <mail:ignoreMessageProperties>
           <value type="java.lang.String">org.apache.servicemix.mail.to</value>
           <value type="java.lang.String">org.apache.servicemix.mail.bcc</value>
           <value type="java.lang.String">org.apache.servicemix.mail.cc</value>
     </mail:ignoreMessageProperties>

 </mail:sender>

</beans>

The above definition will create a mail sender endpoint which connects to a SMTP server. It will use the TO adress specified in receiver attribute because we are ignoring the org.apache.servicemix.mail.to property of the message which would normally hold the value for the receiver. Also we do not want to send the mail to the BC and BCC receivers again so we also skip those properties.

How it works

The mail poller will poll the specified mail box every 30 seconds and grab all available unprocessed mails. Those mails will be simply forwarded to the mail sender endpoint. The mail sender endpoint will receive those messages and throws away all message properties you defined in the "ignoreProps" list. Then a mail is generated out of the message and sent to the specified receiver. After that is done, the original exchange from the mail poller will be set to done state and that will lead to set that mail to seen state in the mail box. (or deleted if you specified it like this) If an error occurs in between, there will be a roll back and the polled mail will be polled again in the next cycle.

Test it with ServiceMix 4

Just take the following file, modify the mail account settings and forward adress (see ENTITY defs) and then drop it into the deploy folder of your ServiceMix 4 installation.

mailForwarder.xml
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!-- defines used within this configuration -->
     <!DOCTYPE schema[ 
 	<!ENTITY pollConnectionURI          "pop3://pop.myprovider.com?user=lhein;password=verysecret">
 	<!ENTITY sendConnectionURI          "smtp://smtp.myprovider.com?user=lhein;password=verysecret">
        <!ENTITY forwardMail                "[email protected]">
     ]> 
     
 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:osgi="http://www.springframework.org/schema/osgi"
        xmlns:ex="http://servicemix.apache.org/examples/mail"
        xmlns:mail="http://servicemix.apache.org/mail/1.0"
        xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                     
        http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
        http://servicemix.apache.org/file/1.0 http://servicemix.apache.org/file/1.0/servicemix-file.xsd">
    
     <!-- this bean has to be here always, otherwise no endpoints are recognized within this file -->
     <bean class="org.apache.servicemix.common.osgi.EndpointExporter" />
 
     <!-- this has to be here because we need to translate system variables -->
     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
 
     <manifest>
        Bundle-Version = 1.0.0
        Bundle-Name = Apache ServiceMix :: Examples :: Email Forwarder
        Bundle-SymbolicName = org.apache.servicemix.mail.examples.forwarder
        Bundle-Description = An example for an email forwarder
        Bundle-Vendor = Apache Software Foundation
        Require-Bundle = servicemix-mail
     </manifest>
 
   <mail:poller service="ex:mailPoller"
                endpoint="pollerEndpoint"
                targetService="ex:mailSender"
                period="30000"
                connection="&pollConnectionURI;"
                deleteProcessedMessages="false"
                processOnlyUnseenMessages="true" />
 
   <mail:sender service="ex:mailSender" 
                endpoint="mailEndpoint" 
                connection="&sendConnectionURI;"
                receiver="&forwardMail;" >
    
      <mail:ignoreMessageProperties>
            <value type="java.lang.String">org.apache.servicemix.mail.to</value>
            <value type="java.lang.String">org.apache.servicemix.mail.bcc</value>
            <value type="java.lang.String">org.apache.servicemix.mail.cc</value>
      </mail:ignoreMessageProperties>
  
   </mail:sender>
      
 </beans>