Enterprise Integration Zone is brought to you in partnership with:

I'm Singaram Subramanian, and I work with CSC India as a Software Developer. My blog is an attempt to share my learnings with all (mainly, for those who desperately mine google finding ways to solve problems, fix issues, learn about a Java/Open source software, or deciding on tough choices etc. during software development as I do). Singaram is a DZone MVB and is not an employee of DZone and has posted 36 posts at DZone. You can read more from them at their website. View Full User Profile

Getting started with Spring Integration v2 and Enterprise Integration Patterns – A Simple Example using File and Mail Adapters

09.25.2011
| 9927 views |
  • submit to reddit

I’ve recently had a requirement to do some Enterprise Integration stuff and tried out Spring Integration for it. I’ve found it to be simple, easy-to-use, and flexible. So, I thought of sharing it with you all.

Here’s the requirement: A daemon program should look for XML files in a particular directory every ‘n’ minutes and if a file is found, it should read the XML data from the file and send it to a mailbox.

It’s pretty doable with plain Java itself, but Spring Integration framework greatly simplifies this task with its’ rich set of adapters.

Here’s what Mark Fisher says about Spring Integration @ http://www.springsource.org/spring-integration

Spring Integration provides an extension of the Spring programming model to support the well-known Enterprise Integration Patterns. It enables lightweight messaging within Spring-based applications and supports integration with external systems via declarative adapters. Those adapters provide a higher-level of abstraction over Spring’s support for remoting, messaging, and scheduling. Spring Integration’s primary goal is to provide a simple model for building enterprise integration solutions while maintaining the separation of concerns that is essential for producing maintainable, testable code.

Okay, let’s jump into the code straightaway. You can use this code as a kind of archetype and go ahead with your implementations. You always have Spring Integration Reference for your help! Btw, this example also guides you on the Spring configuration required to send emails through your Gmail account.

Download the source code of this example here.

SpringIntegrationDemoMain.java

package singz.samples.eai.springintegration;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * @author Singaram Subramanian
 */

public class SpringIntegrationDemoMain
{
 public static void main( String[] args )
 {
 // Instantiate Spring application context with the bean definitions
 // and the integration flow
 new ClassPathXmlApplicationContext("integration-context.xml");

 // Indefinite while loop - just to keep this program running!
 while(true){}
 }
}

integration-context.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- @author Singaram Subramanian -->

<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
 xmlns="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:file="http://www.springframework.org/schema/integration/file"
 xmlns:mail="http://www.springframework.org/schema/integration/mail"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file-2.0.xsd http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail-2.0.xsd">

 <beans:bean id="mailTransformerBean"
 class="singz.samples.eai.springintegration.MailTransformer">
 <beans:property name="mailTo" value="XXX@gmail.com" />
 <beans:property name="mailFrom" value="XXX@gmail.com" />
 <beans:property name="mailSubject" value="Spring Integration - Test Mail" />
 </beans:bean>

 <beans:bean id="mailSender"
 class="org.springframework.mail.javamail.JavaMailSenderImpl">
 <beans:property name="host" value="smtp.gmail.com" />
 <beans:property name="port" value="587" />
 <beans:property name="username" value="XXX" />
 <beans:property name="password" value="XXX" />
 <beans:property name="javaMailProperties">
 <beans:props>
 <beans:prop key="mail.smtp.auth">true</beans:prop>
 <beans:prop key="mail.smtp.starttls.enable">true</beans:prop>
 </beans:props>
 </beans:property>
 </beans:bean>

 <channel id="filesIn" />
 <channel id="mailMsgTransformer" />
 <channel id="outboundMail" />

 <!-- Here's the Spring Integration flow -->

 <!-- This demo application flow starts with a file channel adapter that
 looks for XML files in a particular directory (C:\FileServer) every 5 seconds -->
 <file:inbound-channel-adapter channel="filesIn"
 directory="C:\FileServer" prevent-duplicates="true" filename-pattern="*.xml">
 <poller fixed-rate="5000" />
 </file:inbound-channel-adapter>

 <!-- This transformer component reads data from the XML file coming from
 filesIn channel and converts it to a String and passes that to another transformer
 component, MailMsgTransformer, which constructs a mail message out of it -->
 <file:file-to-string-transformer
 input-channel="filesIn" output-channel="mailMsgTransformer"
 delete-files="true" charset="UTF-8" />

 <transformer ref="mailTransformerBean" input-channel="mailMsgTransformer"
 method="transform" output-channel="outboundMail" />

 <!-- Sends the mail to the mailbox with the credentials defined by mailSender bean -->
 <mail:outbound-channel-adapter channel="outboundMail"
 mail-sender="mailSender" />

</beans:beans>

MailTransformer.java

package singz.samples.eai.springintegration;

import java.io.ObjectInputStream.GetField;
import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.integration.Message;
import org.springframework.mail.MailMessage;
import org.springframework.mail.SimpleMailMessage;

/*
 * @author Singaram Subramanian
 *
 * MailTransformer constructs a simple mail message out of the payload (XML data in this case)
 * that the incoming Message instance carries with it.
 */
public class MailTransformer {
 private String mailTo;
 private String mailFrom;
 private String mailSubject;

 private static Logger logger = Logger.getLogger(MailTransformer.class);

 public String getMailTo() {
 return mailTo;
 }

 public void setMailTo(String mailTo) {
 this.mailTo = mailTo;
 }

 public String getMailFrom() {
 return mailFrom;
 }

 public void setMailFrom(String mailFrom) {
 this.mailFrom = mailFrom;
 }

 public String getMailSubject() {
 return mailSubject;
 }

 public void setMailSubject(String mailSubject) {
 this.mailSubject = mailSubject;
 }

 public MailMessage transform(Message<?> message) {
 Object payload = message.getPayload();
 String mailText = (payload != null) ? payload.toString()
 : "File is empty";

 logger.info("XML payload data from the file: " + mailText);

 MailMessage msg = new SimpleMailMessage();

 msg.setTo(mailTo);
 msg.setFrom(mailFrom);
 msg.setSubject(mailSubject);
 msg.setSentDate(new Date());
 msg.setText(mailText);

 logger.info("Constructed the mail to be sent to the mailbox");

 return msg;
 }

}

About Enterprise Integration Patterns

Enterprise Integration Patterns is a book by Gregor Hohpe and Bobby Woolf and describes a number of design patterns for the use of enterprise application integration and message-oriented middleware. These patterns can be implemented without much coding through Apache Camel, Fuse Mediation Router or the maturing Spring Integration.

Here’s an excerpt from http://www.eaipatterns.com/ on Enterprise Integration,

Why Do We Need Integration?

Today’s business applications rarely live in isolation. Users expect instant access to all business functions an enterprise can offer, regardless of which system the functionality may reside in. This requires disparate applications to be connected into a larger, integrated solution. This integration is usually achieved through the use of some form of “middleware”. Middleware provides the “plumbing” such as data transport, data transformation, and routing.

What Makes Integration so Hard?

Architecting integration solutions is a complex task. There are many conflicting drivers and even more possible ‘right’ solutions. Whether the architecture was in fact a good choice usually is not known until many months or even years later, when inevitable changes and additions put the original architecture to test. Unfortunately, there is no “cookbook” for enterprise integration solutions. Most integration vendors provide methodologies and best practices, but these instructions tend to be very much geared towards the vendor-provided tool set and often lack treatment of the bigger picture, including underlying guidelines, principles and best practices.

Asynchronous Messaging Architectures

Asynchronous messaging architectures have proven to be the best strategy for enterprise integration because they allow for a loosely coupled solution that overcomes the limitations of remote communication, such as latency and unreliability. The trend towards asynchronous messaging has manifested itself in a variety of EAI suites as well emerging standards for reliable, asynchronous Web services. Unfortunately, asynchronous messaging is not without pitfalls. Many of the assumptions that hold true when developing single, synchronous applications are no longer valid. What is needed is vendor-independent design guidance on building robust integration architectures based on asynchronous messaging.

How can Patterns Help?

Patterns are a proven way to capture experts’ knowledge in fields where there are no simple “one size fits all” answers, such as application architecture, object-oriented design, or message-oriented integration . Each pattern poses a specific design problem, discusses the considerations surrounding the problem, and presents an elegant solution that balances the various forces or drivers. In most cases, the solution is not the first approach that comes to mind, but one that has evolved through actual use over time. As a result, each pattern incorporates the experience base that senior integration developers and architects have gained by repeatedly building solutions and learning from their mistakes. This implies that we did not “invent” the patterns; patterns are not invented, but rather discovered and observed from actual practice in the field.

 

From http://singztechmusings.wordpress.com/2011/09/18/getting-started-with-spring-integration-v2-a-simple-example-using-file-and-mail-adapters/

Published at DZone with permission of Singaram Subramanian, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Radu Alex replied on Mon, 2011/09/26 - 1:25pm

What if the mail server is down?

I see the point of using an EIP Pattern only in scenarios like this. You will want to retry the message delivery a specified number of times, with a timeout limit (say if you didn't deliver the message in 24 hours, just drop the message and log an error), with a specified delay before each retry and possible the delay can grow exponentially.

You will also want to set up some rules related to the content of the file: XML files containing will go to one mail box, all the other will go to a default mailbox.

And you want to persist the retry message queue between restarts.

I guess you can take out "without much coding" in this case. Or how easily you can select the proper tool - Camel, Fuse, Spring, plain EJB with build-in support for JMS - which unfortunately does not have a specification on how to retry a message, ...

I personally see Camel best suited for this job as you can define rules in DSL expressions. However, you will have to relay on ActiveMQ which I found it very unstable and loosing messages from the retry queue between restarts .

Bottom line: an article which doesn't just scratch the surface and will present a real implementation (and usefull) for an EIP will be great. Didn't see many although...

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.