JavaMail Bridge Extension Swiftlet
The JavaMail Bridge Swiftlet connects both domains, JMS and eMail, and enables JMS clients to send and receive eMails including attachments with plain JMS. The Swiftlet is installed once somewhere within the router network and is now at the disposal of every JMS client. Through this, it is possible to send and receive eMails from JMS clients which are themselves within a network sector from which they have no mail server access.
Sending eMails via Outbound Bridges
An outbound bridge is bound to an input queue or an input topic where it receives a JMS message, creates a JavaMail message from it, translates JMS headers into JavaMail headers, enriches the JavaMail message by optional default headers (e.g. a default bcc
), and transforms the JMS message body into the JavaMail message body. The transformation is done by pluggable transformer classes. The Swiftlet distribution contains 2 pre-built transformer classes, a TextMessageTransformer to send simple text messages and a MultipartTransformer to send complex eMails with any number of attachments. Finally, the resulting JavaMail message is sent to a configured mail server with the SMTP protocol.
It is possible to define an unlimited number of outbound bridges, bound to different queues/topics and external mail servers and thus create a very complex outbound eMail integration.
An outbound bridge can be activated/deactivated via the Scheduler Swiftlet by a schedulable job to send all eMails at once at a specific daytime or in given intervals.
Receiving eMails via Inbound Bridges
An inbound bridge is bound to a mail account on a particular mail server. It receives JavaMail messages either by the POP3 or by the IMAP protocol. To protect against denial-of-service attacks, an inbound bridge can be configured to receive only a limited number of messages per retrieve interval and/or reject messages which exceed a configured maximum size. For each received JavaMail message, a JMS message is created by a pluggable transformer class which transforms the JavaMail message body into the JMS message body, JavaMail headers are translated into JMS message properties, the JMS message is enriched by default properties and will be sent to a JMS destination which can be either a queue or a topic. The Swiftlet distribution contains 2 pre-built transformer classes, a TextMessageTransformer to receive simple text messages and a MultipartTransformer to receive complex eMails with any number of attachments.
It is possible to define an unlimited number of inbound bridges, bound to different queues/topics and external mail servers and thus create a very complex inbound eMail integration.
An inbound bridge can be activated/deactivated via the Scheduler Swiftlet by a schedulable job to receive all eMails at once at a specific daytime or in given intervals.
Outbound Bridges
An outbound bridge is bound to a queue or topic where it receives JMS messages. The format of the JMS messages is dependent on the transformer class of the outbound bridge. The JMS message will be transformed into a JavaMail message and will be sent to a configured mail server via SMTP.
Creating an Outbound Bridge
A queue or a topic serves as the input source to the outbound bridge. Before you create the bridge, ensure that the queue or topic exists.
Use the SwiftMQ Explorer App, connect, and select the JavaMail Bridge Swiftlet
/ Outbound Bridges
:
Click Create a new Entity
you'll see a dialog where you can specify your bridge configuration:
Field description:
Attribute | Meaning |
---|---|
Name | Some unique name of your choice. |
Enabled | If checked, the bridge will be activated. Since you have not finished your configuration yet, don't enable it now! |
Error Policy | Defines how to handle wrong input messages. See below. |
Error Queue | The error queue for this bridge. |
Retry Interval | The interval in ms in which the bridge tries to reconnect to the mail server in case the mail server is down. |
Mail Log Enabled | Logs every outgoing message in a log file (see Log Swiftlet). |
Send Multipart Text as HTML | Only for multipart messages. If true, set content type of the first body part to text/html. Default is text/plain. |
SMTP Host | The DNS name or the IP address of your mail server. |
SMTP Authentication Enabled | If enabled, used SMTP Username and SMTP Password for SMTP authentication. |
SMTP Username | Name of the user for SMTP authentication. |
SMTP Password | Password for SMTP authentication. |
Source Name | The name of the queue or the topic. The source has to be defined on the local router before you create the bridge. |
Source Type | Select either queue or topic here. |
Reuse Transport | If true, creates the SMTP transport once, reuses it and closes it when the bridge will be disabed. This is the fastest option but mail servers may disconnect the SMTP connection after a while. If false, a new SMTP transport is created on every run. This is slower. |
Transformer Class | The name of the transformer class to use for this bridge (see below). |
Error Policy
Each outbound bridge has an attribute Error Policy
which defines how to proceed in case the transformation fails (transformer throws an exception). Possible values for the error policy are:
Policy | Meaning |
---|---|
| The input message will be deleted. |
| (default) The input message will be flagged as error and will be send to the defined error queue, see below. |
| It will be retried to transform the input message within the next interval. This is only useful if the transformer depends on some kind of external state, e.g. availablity of a database. |
If the error policy is error_queue
, the attribute error-queue
must contain a local queue name. This queue can be shared by all or unique per outbound bridge. It will be automatically created when the bridge starts. In case the transformer throws an exception, the input JMS message will be flagged with the following JMS vendor properties and forwarded to the error queue:
Property | Meaning |
---|---|
| Contains the exception message from the transformer. |
| Contains the name of the outbound bridge. |
Creating Default Headers
Default headers are useful if you want that every mail should be archived, for example. In that case, you'd create a default header for bcc
. Or if you have a default subject to be used if no subject is specified in the JMS message. Technically, all defined default headers are set in the outgoing mail message and may be overwritten by headers, translated from the JMS message. So in fact, you don't need to specify any headers in the JMS message but can define them statically for the bridge as default headers.
You can set any valid Mime header, e.g. X-Mailer
to store the name of an eMail client. The following header names are keywords and have special meaning/handling:
sender
: The sender's eMail address.from
: TheFrom
eMail address.to
: TheTo
recipient's eMail address.cc
: Thecc
recipient's eMail address.bcc
: Thebcc
recipient's eMail address.subject
: The default subject.
To define default headers, select the Default Headers
node of your newly created bridge:
Then specify a default header:
Repeat these steps to create additional default headers.
Defining Header Translations
A header translation defines a translation from a JMS message property into a mail header. Any valid Mime header can be specified. Mail headers with names sender
, from
, to
, reply-to
, cc
, bcc
, and subject
are keywords and have a special meaning/handling (see above Creating Default Headers
). For example, if a JMS client sends newsletters with addresses from a database or an order confirmation to a customer, it would specify JMS message properties in its message which are translated into from
, to
, and subject
. If it stores the order number in the JMS message, a translation into X-ORDERNO
could be defined.
To translate the JMS message id into a mail header, specify JMSMessageID
, for the JMS correlation id specify JMSCorrelationID
as the message property name.
The header translation is done after the default headers are set in the mail message so they overwrite default headers.
To define a header translation, select the Header Translations
node:
Then specify a header translation:
Here is a translation into a custom mail header:
Repeat these steps to create additional header translations.
Defining JavaMail Properties
Depending on the connected mail server products (e.g. one bridge Sendmail, another one Kerio Mailserver), it may be necessary to configure different sets of JavaMail properties for each bridge.
The properties are used to create the JavaMail Session object which is done when the bridge is enabled. So whenever a property is added, removed, or changed, the bridge must be disabled and reenabled to activate the changes.
To define a JavaMail property, select the JavaMail Properties
node of your newly created bridge:
Then specify a JavaMail property:
Repeat these steps to create additional JavaMail properties.
Activating the Bridge
All necessary configurations have been finished now and you can activate the bridge by checking the Enabled
attribute:
The bridge is now active and is listening to the input source.
Outbound Message Transformer
An outbound message transformer is responsible for transforming a JMS message body into a JavaMail message body. It hides the actual message content and structure from the rest of the bridge. Therefore, a JMS client sends JMS messages which correspond with the configured transformer. Since transformers are pluggable, a developer can create his own transformer class which he uses for his JMS clients. This custom transformer class can use custom classes in an ObjectMessage, for example.
For convenience, the JavaMail Bridge Swiftlet includes two pre-built outbound transformers which fit most requirements: A TextMessageTransformer
which uses text messages, and a MultipartTransformer
that uses ObjectMessages with a java.util.ArrayList
including text and attachments.
com.swiftmq.extension.javamail.outbound.TextMessageTransformer
The TextMessageTransformer
accepts a JMS TextMessage and converts it to a mail message body with MIME type text/plain
. It's a very basic transformer. Following the relevant parts of a JMS client which sends a TextMessage to an outbound bridge with a configured TextMessageTransformer
.
Example:
TextMessage msg = session.createTextMessage();
msg.setStringProperty("MailSubject","TestMail, please ignore!");
msg.setStringProperty("FromAddress","testsender@mycompany.com");
msg.setStringProperty("ToAddress","testrecipient@mycompany.com");
for (int i = 0; i < nMsgs; i++)
{
msg.setText("Hello,\n\n This is Msg No: " + (i + 1));
sender.send(msg);
}
For this example, the outbound bridge configuration has to have defined header translations for MailSubject
into subject
, FromAddress
into from
, and ToAddress
into to
.
Hint: To send the mail message with MIME type text/html
, either define a default header or a header translation for message header Content-Type
, respectively.
com.swiftmq.extension.javamail.outbound.MultipartTransformer
The MultipartTransformer
accepts an ObjectMessage containing a java.util.ArrayList
. We have taken this approach to avoid having vendor-specific classes at the JMS client. The ArrayList
has to have the following structure:
Element | Content |
---|---|
0 | A |
1-n | Optional. A |
The HashMap
objects on the ArrayList
elements 1-n are optional. One can also only send an ArrayList
with a single String
element. A HashMap
contains each a single attachment plus some properties describing the attachment:
Property | Content |
---|---|
| The filename of the attachment. This is optional. If not set, the mail server will choose one. |
| The MIME type. This is optional. If not set, the mail server will choose one (mostly |
| Contains the actual attachment in form of a |
| Contains the transfer encoding of this attachment. It can be used to force a particular encoding per attachment, e.g. |
The MultipartTransformer
takes the ArrayList
out of the ObjectMessage, and converts the String
from element 0 into the mail message body with MIME type text/html
if Send Multipart Text as HTML
is set to true, otherwise text/plain
(default). If set, it converts all HashMaps
on elements 1-n into mail message body parts.
The following example contains the relevant code snippets of a JMS client which sends emails with attachments. It takes filenames as parameters of the main method, loads the files, and sends them as attachments. As you will see, it's very easy:
Example:
private static byte[] loadFile(String fn) throws Exception
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fn));
int c;
while ((c=bis.read())!=-1)
bos.write(c);
return bos.toByteArray();
}
private static String getExtension(String fn) throws Exception
{
String s = new File(fn).getName();
return s.substring(s.lastIndexOf('.')+1);
}
// excerpt from the main method
ObjectMessage msg = session.createObjectMessage();
msg.setStringProperty("MailSubject","Multipart TestMail, please ignore!");
msg.setStringProperty("FromAddress","testsender@mycompany.com");
msg.setStringProperty("ToAddress","testrecipient@mycompany.com");
for (int i = 0; i < nMsgs; i++)
{
ArrayList al = new ArrayList();
// add the actual message at element 0
al.add("Message No "+(i+1));
// add all attachment files at 1-n
if (args.length > 4)
{
for (int j=4;j<args.length;j++)
{
HashMap hm = new HashMap();
hm.put("filename",args[j]);
hm.put("content-type","application/"+getExtension(args[j]));
hm.put("content",loadFile(args[j]));
hm.put("encoding","base64"); // Always use base64 encoding
al.add(hm);
}
}
msg.setObject(al);
sender.send(msg);
}
Creating your own Transformer
The TextMessageTransformer
and the MultipartTransformer
are sufficient for most use cases. However, consider the case where you have already a working infrastructure where you send events to topics. For example, if a customer registers on a website and there will be a message published containing the new customer record in XML form. So you could easily write a custom transformer that extracts the relevant data including eMail address out of the XML and send him a "Welcome to our site!" eMail. You only have to create an outbound bridge with your custom transformer and let the bridge listen to the particular topic.
To create a custom transformer, you have to implement one of the following interfaces:
com.swiftmq.extension.javamail.outbound.Transformer
or
com.swiftmq.extension.javamail.outbound.Transformer2
Then create a jar file including your transformer class and all further custom classes you use and put it into the JavaMail Bridge Swiftlet deployment directory. The Swiftlet will be automatically redeployed and you can define your bridge.
Inbound Bridges
An inbound bridge is bound to a queue or topic where it sends JMS messages. It receives JavaMail messages from an account of a configured mail server either by POP3 or IMAP, respectively. The format of the JMS messages is dependent on the transformer class of the inbound bridge. The JavaMail message will be transformed into a JMS message and will be sent to the configured queue or topic.
Creating an Inbound Bridge
A queue or a topic serves as an output target to the inbound bridge. Before you create the bridge, ensure that the queue or topic exists.
Use the SwiftMQ Explorer App, connect, and select the JavaMail Bridge Swiftlet
/ Inbound Bridges
:
After clicking Create a new Entity
you'll see a dialog where you can specify your bridge configuration:
Field description:
Attribute | Meaning |
---|---|
Name | Some unique name of your choice. |
Enabled | If checked, the bridge will be activated. Since you have not finished your configuration yet, don't enable it now! |
Error Policy | Defines how to handle wrong input messages. See below. |
Mail Host | The DNS name or the IP address of your mail server. |
Mail Host Account Folder | The name of the folder of the mail account. This is usually INBOX. |
Mail Host Account Name | The name of the account at the mail server. |
Mail Host Account Password | The account's password. |
Mail Host Port | The port to use at the mail server. This is dependent on the protocol. For POP3 this is 110, for IMAP this is 143. |
Protocol | Select either pop3 or imap here. |
Max. Messages/Interval | Specifies how many messages should be retrieved from the mail server within one retrieve interval. This is to protect against denial-of-service attacks. |
Retrieve Interval | Specifies the interval in ms in which the mail server is polled on new messages. |
Target Message Delivery Mode | Specifies the JMS delivery mode to use. Select either persistent or non-persistent here. |
Target Message Priority | Specifies the JMS priority to use. Select a value between 1 and 9 here. |
Target Message Time To Live | Specifies the JMS expiration time for messages. 0 means no expiration. |
Target Name | The name of the queue or the topic. The source has to be defined on the local router before you create the bridge. |
Target Type | Select either queue or topic here. |
Target Respect Flow Control | If checked, flow control delays returned from the target are respected and the bridge waits appropriately. |
Transformer Class | The name of the transformer class to use for this bridge (see below). |
Max. Message Size (KB) | Specifies the max. size of messages in KB received by this bridge. |
Error Policy
Each inbound bridge has an attribute Error Policy
which defines how to proceed in case the transformation fails (transformer throws an exception). Possible values for the error policy are:
Policy | Meaning |
---|---|
| The input mail will be deleted. |
| (default) The resulting JMS message will be flagged as error, see section about transformers. |
Protecting against Denial of Service Attacks
Keep in mind that you open SwiftMQ to the outside world once you create an inbound bridge. Someone could easily flood the mail account of your inbound bridge with a large number of huge messages which in turn will bring your JMS clients down. To protect against such denial-of-service attacks you can limit the maximum size of the messages themselves and further limit the number of messages to retrieve within one interval. For example, you can define a retrieve interval of 10 minutes (600000 ms), limit the maximum number of messages to retrieve within one interval to 10, and finally set the maximum size of messages to 1 MB (1024 KB).
Creating Default Properties
The JMS message which will be generated from a JavaMail message can be enriched by JMS message properties. For example, you can create a default property that identifies the message to be created by this bridge and use it later in a message selector at your JMS client.
To define default properties, select the Default Properties
node of your newly created bridge:
Then specify a default property:
Repeat these steps to create additional default properties.
Defining Property Translations
A property translation defines a translation from any valid Mime mail header (e.g. MessageID
, Received
, Content-Type
, X-Mailer
) into a JMS message property. The following mail header names are keywords and have special meaning/handling:
sender
: The sender's eMail address.from
: TheFrom
eMail address.to
: TheTo
recipient's eMail address.cc
: Thecc
recipient's eMail address.bcc
: Thebcc
recipient's eMail address.subject
: The default subject.
The translation will be done after setting the default properties and before the actual message transformation will be done. Therefore, the translation overwrites default properties and may be overwritten from the transformer.
To define a property translation, select the Property Translations
node of your newly created bridge:
Then specify a property translation:
Here is a translation of the mail's Message-ID
header into JMS property MailMessageID
:
Repeat these steps to create additional property translations.
Defining JavaMail Properties
Depending on the connected mail server products (e.g. one bridge Sendmail, another one Kerio Mailserver), it may be necessary to configure different sets of JavaMail properties for each bridge.
The properties are used to create the JavaMail Session object which is done when the resp. bridge is enabled. So whenever a property is added, removed or changed, the bridge must be disabled and reenabled to activate the changes.
To define a JavaMail property, select the JavaMail Properties
node of your newly created bridge:
Then specify a JavaMail property:
Repeat these steps to create additional JavaMail properties.
Activating the Bridge
All necessary configurations have been finished now and you can activate the bridge by checking the Enabled
attribute. Then save the configuration. The bridge is now active and is listening to the input queue or topic, respectively.
Inbound Message Transformer
An inbound message transformer is responsible for transforming a JavaMail message body into a JMS message body. It hides the actual message content and structure from the rest of the bridge. Therefore, a JMS client receives JMS messages which correspond with the configured transformer. Since transformers are pluggable, a developer can create his own transformer class which he uses for his JMS clients. This custom transformer class can use custom classes in an ObjectMessage, for example.
For convenience, the JavaMail Bridge Swiftlet includes 4 pre-built inbound transformers which fit most requirements: 2 TextMessageTransformers that use TextMessages, and 2 MultipartTransformers which use ObjectMessages with a java.util.ArrayList
including text and attachments.
Error Policy
Each inbound bridge has an attribute error-policy
that defines how to proceed in case the transformation fails (the transformer throws an exception). Possible values for the error policy are:
Policy | Meaning |
---|---|
| The input mail will be deleted. |
| (default) The resulting JMS message will be flagged as error, see below. |
There are 2 message properties used to flag the generated JMS messages whether the transformation process succeeded or not:
Property | Meaning |
---|---|
| A Boolean property which is true if the transformer failed. |
| In case of an error it contains the error message. |
If JMS_SWIFTMQ_JAVAMAIL_ERROR
is true, the body of the JMS message is undefined and the JMS_SWIFTMQ_JAVAMAIL_ERROR_TEXT
can be used to log the message or to send a notification to the mail sender in case a property translation has been defined on the from
address.
com.swiftmq.extension.javamail.inbound.TextMessageTransformer
The TextMessageTransformer
accepts JavaMail messages with or without attachments. It uses the first body part with MIME type text/plain
and transforms it into a JMS TextMessage. It's a very basic transformer. Following the relevant parts of a JMS client which receives a TextMessage from an inbound bridge with a configured TextMessageTransformer
.
Example:
for (int i = 0; i < nMsgs; i++)
{
TextMessage msg = (TextMessage) receiver.receive();
boolean isError = msg.getBooleanProperty("JMS_SWIFTMQ_JAVAMAIL_ERROR");
if (isError)
{
System.out.println("Error: " + msg.getStringProperty("JMS_SWIFTMQ_JAVAMAIL_ERROR_TEXT"));
} else
{
System.out.println(">>> New Message from " + msg.getStringProperty("CustomerEMail"));
System.out.println(msg.getText());
System.out.println("<<< New Message");
}
}
For this example, the inbound bridge has to have a property translation from the from
mail header into the CustomerEMail
message property.
com.swiftmq.extension.javamail.inbound.GenericTextMessageTransformer
The GenericTextMessageTransformer
works exactly as the TextMessageTransformer
except it uses text/*
to lookup of the actual message to transform it into a JMS TextMessage. This transformer is useful for mails with a single part of MIME type text/html
or text/plain
. For example, if a mail is received with a single part of MIME type text/html
and the TextMessageTransformer
is used, the mail is not transformed because TextMessageTransformer
looks for a text/plain
MIME type. Therefore, you have to use GenericTextMessageTransformer
to get the mail transformed. The JMS TextMessage will contain the HTML formatted mail text.
com.swiftmq.extension.javamail.inbound.MultipartTransformer
The MultipartTransformer generates an ObjectMessage containing a java.util.ArrayList
. We have taken this approach to avoid having vendor-specific classes at the JMS client. The ArrayList
has the following structure:
Element | Content |
---|---|
0 | A |
1-n | A |
The bridge adds as many HashMaps
to the ArrayList
as attachments are contained in the JavaMail message. Each HashMap
contains the following properties:
Property | Content |
---|---|
| The filename of the attachment. |
| The MIME type. |
| Contains the actual attachment in form of a byte[] array. |
The following example contains the relevant code snippets of a JMS client which receives mails with attachments. It saves the attachments in the corresponding files. As you will see, it's very easy:
Example:
for (int i = 0; i < nMsgs; i++)
{
ObjectMessage msg = (ObjectMessage) receiver.receive();
boolean isError = msg.getBooleanProperty("JMS_SWIFTMQ_JAVAMAIL_ERROR");
if (isError)
{
System.out.println("Error: " + msg.getStringProperty("JMS_SWIFTMQ_JAVAMAIL_ERROR_TEXT"));
} else
{
ArrayList al = (ArrayList) msg.getObject();
System.out.println(">>> New Message from " + msg.getStringProperty("CustomerEMail"));
System.out.println(al.get(0));
System.out.println("<<< New Message");
for (int j = 1; j < al.size(); j++)
{
HashMap map = (HashMap) al.get(j);
System.out.println("Filename : " + map.get("filename"));
System.out.println("Content-Type: " + map.get("content-type"));
byte[] b = (byte[]) map.get("content");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream((String) map.get("filename")));
bos.write(b);
bos.flush();
bos.close();
}
}
}
com.swiftmq.extension.javamail.inbound.GenericMultipartTransformer
The GenericMultipartTransformer
works exactly as the MultipartTransformer
except it uses text/*
to lookup the actual message to transform it into a JMS ObjectMessage. This transformer is useful for mails with a single part of MIME type text/html
or text/plain
. For example, if a mail is received with a single part of MIME type text/html
and the MultipartTransformer
is used, the mail is not transformed because MultipartTransformer
looks for a text/plain
MIME type. Therefore, you have to use GenericMultipartTransformer
to get the mail transformed. The JMS ObjectMessage will contain the HTML formatted mail text at element 0 of the ArrayList
.
Creating your own Transformer
The TextMessageTransformer
and the MultipartTransformer
are sufficient for most use cases. However, there might be cases where you want to create your own content, e.g. XML content in a TextMessage. To do this, you can create your own custom transformer.
To create a custom transformer, you have to implement the following interface:
com.swiftmq.extension.javamail.inbound.Transformer
Then create a jar file including your transformer class and all further custom classes you use and put it into the JavaMail Bridge Swiftlet deployment directory. The Swiftlet will be automatically redeployed and you can define your bridge.
Inbound Mail Filter
Mail filters can be attached to inbound bridges and reject unwanted eMails. The following mail filter types are available:
Header mail filter.
Body mail filter.
Attachment mail filter.
Size mail filter.
Mail filters can be chained and so make complex filtering possible. Each incoming eMail is checked against the configured filters and might be deleted or rejected and bounced back to the sender, depending on the configuration.
Mail Filter Configuration
To create a new mail filter, go to folder Mail Filters
and click Create New Entity ...
:
Click on Create a new Entity
:
A mail filter consists of the following general attributes:
Attribute | Meaning |
---|---|
Name | Some unique name of your choice. Mail filters are processed in lexical order of this name. |
Filter Type | "header", "body", "attachment" or "size". |
Reject On Match | Rejects the eMail if the filter matches or rejects it if it doesn't match. Default is true. This attribute is a way to invert the mail filter. |
Rejection Message | The message which is send back to the sender in case the message is rejected and "Return to Sender" is true. |
Return to Sender | Sends a rejection messages back to the sender if the message is rejected. Default is true. If it is set to false, the eMail is only deleted. |
Each mail filter has different specific properties which can be created here:
Click Create a new Entity
:
Header Mail Filter
A header mail filter can check the following eMail headers:
from
to
cc
bcc
reply-to
subject
The header name, e.g. subject
, must be specified as a property name and a regular expression as the value. In the screenshot above, the mail filter checks the subject of the content of the word VIAGRA
. Multiple properties with different headers can be defined and are handled like an and
condition. For example, if the inbound bridge only accepts eMails from a particular domain and with a keyword in its subject, a from
and subject
property with the appropriate regex needs to be defined.
Body Mail Filter
A body mail filter checks the eMail body against the regular expressions of the filter properties. Multiple properties can be defined and are handled like an and
condition. The name of the property can be freely selectable. The value contains the regular expression. For example:
Note that the mail filter uses DOTALL
for the regex so the regex doesn't need to care about linefeeds.
Attachment Mail Filter
This filter checks the MIME-type of attachments. The name of the property must be mime-type
and the value of the MIME-type is checked against those of the attachments. The value is NOT a regular expression but a regular MIME-type, e.g. application/pdf
for PDF documents or application/*
for everything under the application
media type. Only 1 property mime-type
can be defined. To filter multiple attachment MIME types, multiple filters can be defined.
The following attachment filter lets only pass PDF documents:
Size Mail Filter
A size mail filter checks the size of the eMail. There can only 1 filter property with the name max-size
be defined. The value of the property is the maximum size of an eMail in KB. Setting Reject on Match
to false has no effect on this mail filter. The following example defines a size mail filter that rejects all eMail with a size greater than 1 MB:
Chaining of Mail Filters
Mail filters can be easily chained to create more complex filters. Each filter of the chain is handled in an or
fashion. For example, to create a filter for an internal support system with the following conditions:
Sender must be from a
wombat.com
domain.Subject must contain
TICKET#
.Body must not contain
VIAGRA
,PORN
.Attachment accepted is PDF files only.
eMail size must be less or equal to 5 MB.
this chain needs to be defined (covers the whole configuration from the routerconfig.xml):
<swiftlet name="xt$javamail">
<inbound-bridges>
<inbound-bridge name="support-inbound" enabled="true"
mail-host="mx.wombat.com" mail-host-account-name="xxx" mail-host-account-password="xxx"
mail-host-port="143" protocol="imap" target-name="support-inbound"
transformer-class="com.swiftmq.extension.javamail.inbound.MultipartTransformer">
<default-properties/>
<mail-filter-definition mail-filter-reject-from-address="noreply@wombat.com"
mail-filter-reject-queue="support-reject">
<mail-filters>
<mail-filter name="01"
filter-type="header"
rejection-message="This is an internal support system for wombat.com only!"
return-to-sender="true">
<filter-properties>
<filter-property name="from" value=".*@wombat.com"/>
<filter-property name="subject" value=".*TICKET#.*"/>
</filter-properties>
</mail-filter>
<mail-filter name="02" filter-type="body">
<filter-properties>
<filter-property name="01" value=".*VIAGRA.*"/>
</filter-properties>
</mail-filter>
<mail-filter name="03" filter-type="body">
<filter-properties>
<filter-property name="01" value=".*PORN.*"/>
</filter-properties>
</mail-filter>
<mail-filter name="04" filter-type="attachment"
reject-on-match="false"
rejection-message="Only PDF attachments accepted!"
return-to-sender="true">
<filter-properties>
<filter-property name="mime-type" value="application/pdf"/>
</filter-properties>
</mail-filter>
<mail-filter name="05" filter-type="size"
rejection-message="We don't accept eMails greater than 5 MB!"
return-to-sender="true">
<filter-properties>
<filter-property name="max-size" value="5120"/>
</filter-properties>
</mail-filter>
</mail-filters>
</mail-filter-definition>
<property-translations/>
</inbound-bridge>
</inbound-bridges>
<outbound-bridges>
<outbound-bridge name="support-reject" enabled="true" smtp-host="mx.wombat.com" source-name="support-reject">
<default-headers/>
<header-translations>
<header-translation name="01" message-property="from"/>
<header-translation name="02" mail-header="to" message-property="to"/>
<header-translation name="03" mail-header="subject" message-property="subject"/>
</header-translations>
</outbound-bridge>
</outbound-bridges>
</swiftlet>
Reject Configuration
Whenever an eMail is rejected and the respective mail filter is configured to send the mail back to the sender, a message is stored into a reject queue which must serve as the input queue for an outbound bridge. 2 properties can be defined to configure the reject sender eMail address and the reject queue name:
The JMS message stored in the reject queue is a JMS TextMessage so the appropriate outbound bridge must have a TextMessageTransformer
. The message properties set in the JMS TextMessage are:
from
to
subject
The outbound bridge must have the appropriate property translations defined.
Job Scheduling
The JavaMail Bridge Swiftlet registers jobs in job group JavaMail
at the Scheduler Swiftlet:
These jobs can be scheduled via the Scheduler Swiftlet to run at specific times or in intervals, based on calendars and so on.
Outbound Bridge
The Outbound Bridge job activates an outbound bridge on job start and deactivates it on job stop. The name of the bridge must be specified as a parameter. The job requires setting a maximum runtime to deactivate the bridge. Otherwise, it would be active forever.
The implementation of the Outbound Bridge job is quite simple. It sets the enabled
attribute to true
on job start and to false
on job stop. Therefore, an outbound bridge that should run as a job should be initially disabled.
Parameter | Mandatory | Description |
---|---|---|
Bridge Name | Yes | Name of the outbound bridge. |
Inbound Bridge
The Inbound Bridge job activates an inbound bridge on job start and deactivates it on job stop. The name of the bridge must be specified as a parameter. The job requires setting a maximum runtime to deactivate the bridge. Otherwise, it would be active forever.
The implementation of the Inbound Bridge job is quite simple. It sets the enabled
attribute to true
on job start and to false
on job stop. Therefore, an inbound bridge that should run as a job should be initially disabled.
Parameter | Mandatory | Description |
---|---|---|
Bridge Name | Yes | Name of the inbound bridge. |
Installation
The installation takes place via 'hot deployment'. See the documentation of the Deploy Swiftlet for further information.
Configuration
The configuration of the JavaMail Bridge Extension Swiftlet is defined within the element
<swiftlet name="xt$javamail" .../>
of the router's configuration file.
Attributes of Element "swiftlet"
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
collect-interval | java.lang.Long | No | Collect Interval (ms) for the Usage Section |
Values
Attribute | Values |
---|---|
collect-interval | Default: 10000 |
Element List "outbound-bridges", Parent Element: "swiftlet"
Outbound Bridges. This element list contains zero or more "outbound-bridge" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Outbound Bridge |
enabled | java.lang.Boolean | No | Enables/Disables this Bridge |
maillog-enabled | java.lang.Boolean | No | Enables/Disables this the Mail Log of this Bridge |
smtp-host | java.lang.String | Yes | DNS Name of the SMTP Host |
smtp-authentication-enabled | java.lang.Boolean | No | Enables/Disables SMTP Authentication |
smtp-username | java.lang.String | No | SMTP Username |
reuse-transport | java.lang.Boolean | No | Specifies whether the SMTP Transport is reused |
send-multipart-text-as-html | java.lang.Boolean | No | Specifies whether multipart mail text should be send as text/html |
smtp-password | java.lang.String | No | SMTP Password |
error-policy | java.lang.String | Yes | How to handle errorneous Input Messages |
error-queue | java.lang.String | Yes | Name of the Error Queue for this Bridge |
retryinterval | java.lang.Long | No | Retry Interval (ms) for Re-Connect |
source-name | java.lang.String | Yes | Name of the Source |
source-type | java.lang.String | No | Type of the Source |
transformer-class | java.lang.String | No | Name of the Transformer Class |
Values
Attribute | Values |
---|---|
enabled | Default: false |
maillog-enabled | Default: false |
smtp-host | |
smtp-authentication-enabled | Default: false |
smtp-username | |
reuse-transport | Default: true |
send-multipart-text-as-html | Default: false |
smtp-password | |
error-policy | Choice: delete error_queue retry |
error-queue | Default: javamail-outbound-error |
retryinterval | Default: 60000 |
source-name | |
source-type | Choice: queue topic |
transformer-class | Default: com.swiftmq.extension.javamail.outbound.TextMessageTransformer |
Element List "header-translations", Parent Element: "outbound-bridge"
Header Translations. This element list contains zero or more "header-translation" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Header Translation |
message-property | java.lang.String | Yes | Message Property Name |
mail-header | java.lang.String | Yes | Mail Header Name |
Values
Attribute | Values |
---|---|
message-property | |
mail-header | Default: from |
Element List "default-headers", Parent Element: "outbound-bridge"
Default Headers. This element list contains zero or more "default-header" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Default Header |
value | java.lang.String | Yes | Value |
Values
Attribute | Values |
---|---|
value |
Element List "javamail-properties", Parent Element: "outbound-bridge"
JavaMail Properties. This element list contains zero or more "javamail-property" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this JavaMail Property |
value | java.lang.String | Yes | Value |
Values
Attribute | Values |
---|---|
value |
Element List "inbound-bridges", Parent Element: "swiftlet"
Inbound Bridges. This element list contains zero or more "inbound-bridge" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Inbound Bridge |
enabled | java.lang.Boolean | No | Enables/Disables this Bridge |
maillog-enabled | java.lang.Boolean | No | Enables/Disables this the Mail Log of this Bridge |
error-policy | java.lang.String | Yes | How to handle errorneous Input Mails |
mail-host | java.lang.String | Yes | DNS Name of the Mail Host |
mail-host-port | java.lang.Integer | Yes | Port Number (pop3: 110, pop3s: 995, imap: 143, imaps: 993) |
mail-host-account-name | java.lang.String | No | Mail Host Account Name |
mail-host-account-password | java.lang.String | No | Mail Host Account Password |
mail-host-account-folder | java.lang.String | No | Mail Host Account Folder |
protocol | java.lang.String | No | Protocol |
retrieveinterval | java.lang.Long | Yes | Retrieve Interval (ms) |
retrieve-max-messages | java.lang.Integer | Yes | Max. Messages to process per Interval |
target-name | java.lang.String | Yes | Name of the Target |
target-type | java.lang.String | No | Type of the Target |
target-message-deliverymode | java.lang.String | No | Target Message Delivery Mode |
target-message-ttl | java.lang.Long | No | Target Message Time To Live |
target-message-priority | java.lang.Integer | No | Target Message Priority |
target-respect-flowcontrol | java.lang.Boolean | No | Respect Flow Control of the Target |
transformer-class | java.lang.String | No | Name of the Transformer Class |
transformer-max-message-size | java.lang.Integer | No | Max Message Size (KB) |
Values
Attribute | Values |
---|---|
enabled | Default: false |
maillog-enabled | Default: false |
error-policy | Choice: delete flag |
mail-host | |
mail-host-port | Default: 110 |
mail-host-account-name | |
mail-host-account-password | |
mail-host-account-folder | Default: INBOX |
protocol | Choice: pop3 pop3s imap imaps |
retrieveinterval | Default: 600000 |
retrieve-max-messages | Default: 10 |
target-name | |
target-type | Choice: queue topic |
target-message-deliverymode | Choice: persistent non-persistent |
target-message-ttl | Min: 0 |
target-message-priority | Min: 0 |
target-respect-flowcontrol | Default: true |
transformer-class | Default: com.swiftmq.extension.javamail.inbound.TextMessageTransformer |
transformer-max-message-size | Min: -1 |
Element "mail-filter-definition", Parent Element: "inbound-bridge"
Definitions of inbound Mail Filters.
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
mail-filter-reject-from-address | java.lang.String | Yes | The Mail Address used as 'from' in rejected Messages |
mail-filter-reject-queue | java.lang.String | Yes | Name of the Queue to forward rejected Messages |
Values
Attribute | Values |
---|---|
mail-filter-reject-from-address | Default: noreply@domain.com |
mail-filter-reject-queue | Default: mail-filter-reject-queue |
Element List "mail-filters", Parent Element: "mail-filter-definition"
Mail Filter. This element list contains zero or more "mail-filter" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Mail Filter |
filter-type | java.lang.String | Yes | Type of this Mail Filter |
reject-on-match | java.lang.Boolean | No | Rejects Message if this Filter matches |
rejection-message | java.lang.String | No | Message returned to Sender upon Rejection |
return-to-sender | java.lang.Boolean | No | Returns Mail to Sender if rejected by this Filter |
Values
Attribute | Values |
---|---|
filter-type | Choice: header body attachment size |
reject-on-match | Default: true |
rejection-message | |
return-to-sender | Default: false |
Element List "filter-properties", Parent Element: "mail-filter"
Filter Properties. This element list contains zero or more "filter-property" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Filter Property |
value | java.lang.String | Yes | Value |
Values
Attribute | Values |
---|---|
value |
Element List "property-translations", Parent Element: "inbound-bridge"
Property Translations. This element list contains zero or more "property-translation" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Property Translation |
message-property | java.lang.String | Yes | Message Property Name |
mail-header | java.lang.String | Yes | Mail Header Name |
Values
Attribute | Values |
---|---|
message-property | |
mail-header | Default: from |
Element List "default-properties", Parent Element: "inbound-bridge"
Default Properties. This element list contains zero or more "default-property" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this Default Property |
value | java.lang.String | Yes | Value |
Values
Attribute | Values |
---|---|
value |
Element List "javamail-properties", Parent Element: "inbound-bridge"
JavaMail Properties. This element list contains zero or more "javamail-property" elements with this template definition:
Definition
Attribute | Type | Mandatory | Description |
---|---|---|---|
name | java.lang.String | Yes | Name of this JavaMail Property |
value | java.lang.String | Yes | Value |
Values
Attribute | Values |
---|---|
value |
CLI Commands During Deployment
This Swiftlet performs the following CLI commands during deployment:
cc /sys$threadpool/pools
new javamail.outbound
new javamail.inbound
cc /sys$threadpool/pools/javamail.outbound/threads
new extension.xt$javamail.outbound.%
cc /sys$threadpool/pools/javamail.inbound/threads
new extension.xt$javamail.inbound.%
CLI Commands During Undeployment
This Swiftlet performs the following CLI commands during undeployment:
cc /sys$threadpool/pools
delete javamail.outbound
delete javamail.inbound