views:

176

answers:

3

Obviously it's not so difficult to send out emails from a JEE application via JavaMail. What I am interested in is the best pattern to receive emails (notification bounces, mostly)? I am not interested in IMAP/POP3-based approaches (polling the inbox) - my application shall react to inbound emails.

One approach I could think of would be

  • Keep existing MTA (postfix on linux in my case) -> ops team already knows how to configure / operate it
  • For every mail that arrives, spawn a Java app that receives the data and sends it off via JMS. I could do this via an entry in /etc/aliases like myuser: "|/path/to/javahelper" with javahelper calling the Java app, passing STDIN along.
  • MDB (part of JEE application) receives JMS message, parses it, detects bounce message and acts accordingly.

Another approach could be

  • Open a listening network socket on port 25 on the JEE application container.
  • Associate a SessionBean with the socket. Bean is part of JEE application and can parse/detect bounces/handle the messages directly.
  • Keep existing MTA as inbound relay, do all its security/spam filtering, but forward emails to myuser (that pass the filter) to the JEE application container, port 25.

The first approach I have done before (albeit in a different language/setup).

From a performance and (perceived) cleanliness point of view, I think the second approach is better, but it would require me to provide a proper SMTP transport implementation. Also, I don't know if it's at all possible to connect a network socket with a bean...

What is your recommendation? Do you have details about the second approach?

A: 

I don't think the second approach is "cleaner". On the contrary, it requires you to implement a significant part of a standard MTA, so I would recommend against it.

I believe that polling a POP/IMAP server is actually the cleanest way to do this. Why did you decide against it? If the POP/IMAP server and your service are in the same LAN (or even on the same maching), a poll will be quite inexpensive. You can do it every 10-20s for minimum delay, that should not cause problems. While this may look a bit technically inelegant, you will use a standard interoperation protocol (POP3/IMAP), which gives you flexibility while avoiding to reimplement a mailserver.

The approach of spawning a Java app also seems viable, but I'd prefer the polling, because:

a) The interface you use (POP3/IMAP) is more standardized, while the interface you use to "plug in" to the mail server will be server-specific (on Unix, you could use e.g. procmail, but you still depend on specific software)

b) Launching a separate process per mail will probably have much more overhead than polling.

Incidentally: A third approach would be to somehow dump the incoming mails as files into an "incoming" directory (many mailservers can do this), then poll the directory. Polling a directory will be even less expensive than polling a server. Just beware of synchronization issues (reading half-written mail, several concurrent readers reading the same mail file...)

My experience:

I have implemented systems using both approaches (IMAP polling, and spawning a separate process). The polling was for a reasonably large Java app which processed data that people sent to a mailbox; I did not encounter any problems wrt polling. The spawning approach was for a small Perl script; I just did it since it was a simple program that only processed a few mail per day, and plugging into the mailserver was easier than doing IMAP in Perl.

sleske
@sleske: Thx for the detailed response! Unfortunately the MTA does not provide POP3/IMAP facilities (today)... I'll think about which part is easier.
Hank
A: 

The "correct" way according to the JEE architecture would be to have a JCA connector to do inbound/outbound connection with the SMTP server.

The JCA connector can do whatever you want, including threading and connection to external systems with sockets. Actually JMS is just a special kind of JCA connector that connects to JMS broker and delivers message to "regular" MDB. A JCA connector can then poll the SMTP server and delivers the message to a custom MDB.

The best document about JCA is Creating Resource Adapters with J2EE Connector Architecture 1.5, and it does actually use the example of email delivery. Luck you :) I suggest you have a look at it. The code can be found as part of the JEE samples and uses JavaMail, but I don't know if it's production ready.

Related:

ewernli
+1  A: 

Using an ESB - standalone or embeded.

"An ESB brings flow-related concepts such as transformation and routing to a Service-Oriented Architecture. An ESB can also provide an abstraction for endpoints. This promotes flexibility in the transport layer and enables loose coupling and easy connection between services."

For example MULE "Mule ESB is the most widely used open source ESB. A lightweight integration platform and service container, Mule ESB provides features for web services, message routing, mediation, transformation and transaction management, helping developers integrate their applications in hours, not weeks"

How to receive emails via mule http://books.dzone.com/articles/mule-messaging-chapter?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fsoa+(SOA+Zone)

Below is simply configuration which send JMS message as reaction on received message (it is all you need) - define inbound (imap/pop3/etc) - define outbound.

<imap:inbound-endpoint user="bob" password="password" host="localhost" port="65433" checkFrequency="3000"/> 
<jms:outbound-endpoint queue="my.destination" connector-ref="jmsQueueConnector"/>
Maciek Kreft