We have seen how to use a Grails service in a Camel route, but the Apache Camel plugin also allows us to send messages to a Camel route. We can use the sendMessage
method in our controllers and services. We define the starting point of the route and a message object and we can send it.
For our example we are going to send an e-mail message from a controller. We are using a fire-and-forget method, so we can immediatelly return to the web page and we don't have to wait until the mail communication is finished. Let's start with a Grails application:
$ grails create-app sendmail $ cd sendmail $ grails install-plugin camel
Next we create a controller which will create and send a message to a Camel route:
$ grails create-controller mail
We open the MailController
in an editor and add a mail
closure. Here we get the values from the request parameters name and email (the web page with a form and two input fields name and email is created next). We invoke the sendMessage
method to send a map message to the route starting point seda:mailQueue. The SEDA component from Apache Camel allows asynchronuous communication, so we immediatelly return to our controller after the message is sent. To get more robust asynchronuous communication we could use for example ActiveMQ. Finally we return to the web page with a flash message we can display.
class MailController { def mail = { if (params.name != null && params.email != null) { sendMessage "seda:mailQueue", [name: params.name, email: params.email] flash.message = "Check your e-mail for new messages." } } }
The controller will look for a file grails-app/views/mail/mail.gsp
to display a web page. So let's create it. The page only needs a form with input fields for name and e-mail:
<%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Mail with Apache Camel and Grails</title> </head> <body> <h1>Mail with Apache Camel</h1> <g:if test="${flash.message}"> <div class="message">${flash.message}</div> </g:if> <g:form method="POST"> Name: <g:textField name="name"/><br /> E-mail: <g:textField name="email"/><br /> <g:submitButton name="submit" value="Send mail"/> </g:form> </body> </html>
Okay we have created the controller and web page. Next we create the Camel route:
$ grails create-route mail
The route will listen with the SEDA component for incoming messages. The message contains a map with the name and e-mail values. We use these values to create the content of an e-mail message. The content is HTML so we can show off Groovy's builder support. We also define the subject, to and from headers of the e-mail message. Then we use Camel's mail component to send the e-mail via SMTP.
import org.codehaus.groovy.grails.commons.* class MailRoute { def configure = { def config = ConfigurationHolder.config from("seda:mailQueue") .process { def name = it.in.body.name def to = it.in.body.email def html = new groovy.xml.StreamingMarkupBuilder().bind { html { body { p "${name}," p { mkp.yield "Thank you for your interest in " a href:'http://camel.apache.org', "Apache Camel" mkp.yield "." } p { i "P.S. Grails rocks" } } } } it.out.setBody html.toString() it.out.setHeader "to", to it.out.setHeader "from", "h.kleinikkink@gmail.com" it.out.setHeader "subject", "Mail sent from Apache Camel" } .to("smtps://smtp.gmail.com?username=${config.smtps.user}&password=${config.smtps.password}&contentType=text/html") } }
The Camel mail component has a dependeny on the JavaMail API libraries. We must download the libraries and add them to our lib
directory. Or we can install the Grails mail plugin, which contains the JavaMail API libraries already. This way the libraries are automatically added to our application. (grails install-plugin mail
)
And we are done. We can run our application and start sending e-mails:
$ grails run-app
Notice how the web page returns immediatelly after we submit the form, because of the asynchronuous SEDA component.