Sending Gmail with Spring Roo and Spring Integration

Introduction

This is the more detailed version of my previous blog “Sending outbound SMTP messages through Gmail with Spring Integration“. Since, I teach the Enterprise Integration with Spring.

In this post, I will walk you though project creation and modification using Spring Roo to configure our basic project components.

Configuration

We will need the following for this demo:




Steps to Full Solution

Part 1: Configuring the Application with Roo

Install Spring Roo 1.1.0.M3

1. Make a directory for your new project:

mkdir /code/simaildemo

cd /code/simaildemo

2. Start Roo by typing roo and press enter, you should get the roo> prompt. If not, check your Roo installation.

    ____  ____  ____
   / __ \/ __ \/ __ \
  / /_/ / / / / / / /
 / _, _/ /_/ / /_/ /
/_/ |_|\____/\____/    1.1.0.M2 [rev 0b3543e]

Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
roo>

3. From the Roo prompt, setup the project

roo> project --topLevelPackage com.gordondickens.simail

4. Now configure your persistence to be Hibernate with Hypersonic SQL in Memory database

roo> persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY

5. Next create the entity class Recipient

roo> entity --class ~.entity.Recipient

6. Now lets configure the 3 necessary fields that you will capture to send an Email.

~.entity.Recipient roo> field string recipientEmail
~.entity.Recipient roo> field string subject
~.entity.Recipient roo> field string messageBody

7. The last functional step is to scaffold the controller and views

~.entity.Recipient roo> controller scaffold --class ~.web.RecipientController --entity ~.entity.Recipient

8. Before we head to the IDE, let’s set logging to DEBUG for the application

~.entity.Recipient roo> logging setup --level DEBUG

9. Now we can exit the Roo Command Shell

~.entity.Recipient roo> exit

10. Start STS

11. Import our project within STS from the menu option

File > Import… > Maven > Existing Maven Projects




Part 2: Configuring Spring Integration

1. Now that the project is loaded in STS, let’s add some necessary dependencies to our Maven pom.xml.

In the <properties> section add:

    <spring.integration.version>2.0.0.M6</spring.integration.version>

In the <dependencies> section add:

<dependency>
   <groupId>org.springframework.integration</groupId>
   <artifactId>spring-integration-core</artifactId>
   <version>${spring.integration.version}</version>
</dependency>
<dependency>
   <groupId>org.springframework.integration</groupId>
   <artifactId>spring-integration-mail</artifactId>
   <version>${spring.integration.version}</version>
</dependency>
<dependency>
   <groupId>javax.mail</groupId>
   <artifactId>mail</artifactId>
   <version>1.4.1</version>
</dependency>

Below is the EIP diagram of the components used in this solution

2. The first component we need to build is the Gateway for sending mail message. To send a message into Spring Integration we will create an interface for Spring to receive the message contents.

You can generate the interface from the Roo Shell view in STS with the following command.

      roo>  interface --class ~.integration.MailGateway

This is very cool… all we need is a single interface method to receive a Recipient class, and Spring Integration does the rest. See the Spring Integration documentation on how to annotate method parameters to add argument values to the message header.

   @Gateway
	public void sendMail(Recipient recipient);

3. Next we need to write a transformer to convert Recipient data into MailMessage. When sending mail via Spring Integration Channel adapters, Spring’s MailMessage object is handled automatically.

Once again, use Roo to generate the shell of our transformer class.

   roo> class --class ~.integration.RecipientMailMessageTransformer

Write a method that will populate a MailMessage object from the inbound Recipient contents.

@Autowired
MailMessage mailMessage;

public MailMessage transform(Recipient recipient) {
   if (recipient == null) {
      return null;
   }

   mailMessage
      .setTo(StringUtils.hasText(recipient.getRecipientEmail()) ? recipient
      .getRecipientEmail() : "");
   mailMessage
      .setSubject(StringUtils.hasText(recipient.getSubject()) ? recipient
      .getSubject() : "");
   mailMessage.setSentDate(new Date(0));
   mailMessage
      .setText(StringUtils.hasText(recipient.getMessageBody()) ? recipient
      .getMessageBody() : "");

   return mailMessage;
}

4. Now that our code is in place, lets wire the integration components via configuration. Spring configuration files are in the src/main/resources/META-INF/spring directory and Roo is configured to pickup any applicationContext*.xml files.

Let’s add the necessary Spring Integration components to a new file in src/main/resources/META-INF/spring named applicationContext-integration.xml.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://www.springframework.org/schema/integration" 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/aop http://www.springframework.org/schema/aop/spring-aop-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/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail-2.0.xsd">

   <channel id="outboundMailChannel" />
   <channel id="xformMailChannel" />
   <channel id="confirmationChannel"/>

   <beans:bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
      <beans:property name="host" value="${email.host}" />
      <beans:property name="port" value="${email.port}" />
      <beans:property name="username" value="${email.account.name}" />
      <beans:property name="password" value="${email.account.password}" />
      <beans:property name="javaMailProperties">
         <beans:props>
            <beans:prop key="mail.smtp.starttls.enable">true</beans:prop>
            <beans:prop key="mail.smtp.auth">true</beans:prop>
         </beans:props>
      </beans:property>
   </beans:bean>

   <gateway id="mailGateway" service-interface="com.gordondickens.simail.integration.MailGateway"
      default-request-channel="xformMailChannel" default-reply-channel="confirmationChannel" />

   <transformer input-channel="xformMailChannel" output-channel="outboundMailChannel"
      ref="mailTransformer" method="transform"/>

   <!-- Configure Mail Sender -->
   <mail:outbound-channel-adapter channel="outboundMailChannel" mail-sender="mailSender" />

   <beans:bean id="mailMessage" scope="prototype">
      <beans:property name="from" value="${email.account.name}"/>
      <beans:property name="replyTo" value="${email.account.name}"/>
   </beans:bean>

   <beans:bean id="mailTransformer"/>
</beans:beans>

5. For additional ease of configuration, let’s externalize email settings in a properties file in src/main/resources/META-INF/spring named email.properties. Roo automatically discovers all *.property files in that directory with property placeholder configuration in applicationContext.xml.

email.account.name=someusername@gmail.com
email.account.password=someacctpasswd
email.host=smtp.gmail.com
email.port=587

6. Now all we have to do is write the code from the controller method to invoke the gateway method “sendMail” and pass the Recipient object.

The great thing about Roo is that is generates all of our CRUD controller methods for us. In this example, we want to customize the behavior of one of those generated methods.

Roo weaves in all the generated code from *.aj (AspectJ) files at compile time. By default, STS hides these from us so we can focus on what is important to us and not the common plumbing.

If you do not see the *.aj files in the package directories, you have to show them. To show the generated files click on the drop down menu (looks like little triangle in upper right corner of the view) in “Package Explorer” choose “Filters…”
and uncheck “Hide generated Spring Roo ITDs”.

To customize the create method we will use “Push-in refactor” to push that method into our controller class where we can invoke the Gateway method.

In “Project Explorer” expand the class “RecipientController_Roo_Controller.aj” so you can see the methods. Right click on the method “create” > “Refactor” > “Push in…”. In the dialog, click “OK”.

7. Modify the RecipientController.java Class

First, let’s Autowire the MailGateway class:

    @Autowired MailGateway mailGateway

Now edit the “RecipientController.java” class and insert the following line in the “create” method before the return statement:

   mailGateway.sendMail(recipient);

Note: the gateway is configured to return a String value but we are not managing return values in this demo.

8. Time to take it for a test toast… go to your project directory and run:

   mvn clean install

if everything compiles successfully, run:

mvn tomcat:run

After the server starts, go to your browser and go to the url “localhost:8080/simail. Create and send a meil message it should send a message to the recipient’s mailbox.



Visualization in STS

As of STS version 2.5.0M3 you can view and edit your Spring Integration flows graphically. In the diagram below we see that when you open your integration context file we can click on the integration-graph tab to work with our flow graphically.




Summary

What we have done here is to use Spring Roo to quickly frame out our application. In order to use Spring Integration:

  1. Added a couple dependencies to our maven pom.xml file
  2. Configured and coded the Message Gateway interface to receive inbound messages
  3. Configured and coded a Message Transformer to convert from our entity class to the MailMessage class
  4. Created an integration specific application context XML file
  5. Configured our Outbound Mail Message Adapter
  6. Connected all the components together using Message Channels

It is certainly possible to solve this use-case with other implementation approaches. So why use Spring Integration?

  • Add incoming adapters via configuration to receive messages from JMS, Mail, File (directories), etc
  • Change the channels to buffer messages
  • Change the channel to a Message WireTap, sending a copy of the message to another endpoint
  • Change the outbound Message Adapter to a different implementation such as JMS, File, etc
  • Have the ability to change the wiring (aka message plumbing) without having to recompile code
  • Because you want to be one of the “cool kids”




Additional Links:

Spring Integration
Spring Integration in Action
SpringSource Certified Training Partner




Download Demo from Git

The project is available in my Git Repo (below). There is a Roo script file named simail.roo for your scripting pleasure.

git://github.com/gordonad/Technophile-Blog-Demos.git

GIT -vs- SVN Reference

About Gordon

Technology enthusiast primarily focused on Java and Open Source projects. Spring Certified Professional and Trainer. http://twitter.com/gdickens http://linkedin.com/in/gordondickens http://github.com/gordonad
This entry was posted in Java, Java Mail, Roo, Spring, Spring Framework, Spring Integration, Spring Roo and tagged , , , , , . Bookmark the permalink.

One Response to Sending Gmail with Spring Roo and Spring Integration

  1. Pingback: Tweets that mention Technophile Blog ยป Sending Gmail with Spring Roo and Spring Integration -- Topsy.com

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>