Adding More Logic with the Email Task in Activiti

This article is based on Activiti in Action , to be published on Fall 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

Introduction

When the employees of the Loan Shark Company decide not to approve of a loan request, the customer is informed by email. The email task is the last step of the loan approval process, as we can see in figure 1.

After this task is completed the process will finish.

NOTE The email task is not an official task of the BPMN 2.0 specification. It, therefore, doesn’t have a dedicated icon and is shown as a regular service task. Activiti uses the email task to enhance business processes that send emails to one or more recipients, including support for cc, bcc, and html content. It’s a bonus!

Before we can implement the email task in BPMN 2.0 XML and test it in Eclipse or run it later on Activiti engine for that matter, we need to set up a mail server first. We will use the Apache James project to do that. When our server is running, we will make a tiny process to test the email task and send Miss Piggy a message. This way, you can see how the email task works and make sure that the James environment is configured correctly.

Getting up and running with Apache James Mail server

Download Apache James from http://james.apache.org and unzip the file in a directory of choice. We are not going to do anything very secure in our loan request example, so we’ll just use the default setup. You can start the server by executing the run.sh or run.bat file in the james_install_dir/bin directory.

After the server is up and running smoothly in the background we need to add a user account so we have somebody to mail to from the process. Start a telnet session with localhost on port 4555; you can login with the preconfigured root user, password root. Then add a user with the following command:

adduser miss.piggy piggy

A user called miss.piggy is added with the email address miss.piggy@localhost and the password piggy. To check if Miss Piggy’s account is actually added, you can execute the listusers command to verify. Figure 2 gives a view on the telnet session to summarize things.

That’s all there is to it. The James mail server is configured correctly and waiting to receive mails on port 25. Back to Activiti!

Defining the email task

Now that our mail server is up and running smoothly, we are ready to define an email task in the BPMN 2.0 XML file. For detailed information concerning different configuration options for the email task within Activiti, you can check out the Activiti user guide. We will stick to the basics for the moment and create a simple standalone process that sends an email to the customer to test the mail server configuration. Let’s take a look at the BPMN 2.0 XML in listing 1.

Listing 1 Simple email task process to test the James configuration

<process id="simpleEmailProcess" >
		<startEvent id="theStart" />
		<sequenceFlow sourceRef="theStart" targetRef="sendMail" />
		<serviceTask id="sendMail" activiti:type="mail"> 						#1
			<extensionElements>
				<activiti:field name="to">
					<activiti:string>miss.piggy@localhost</activiti:string> 		#2
				</activiti:field>
				<activiti:field name="subject"> 						#3
					<activiti:string>Hello ${name}!</activiti:string>
				</activiti:field>
				<activiti:field name="html"> 							#4
					<expression>
						<![CDATA[
							<html>
							<body>
								Hello ${name},<br/><br/> 			#5
								Your loan request has been denied.<br/><br/>
								Kind regards,<br/>
								The Loan Sharks Company.
							</body>
							</html>
						]]>
					</expression>
				</activiti:field>
			</extensionElements>
		</serviceTask>
		<sequenceFlow sourceRef="sendMail" targetRef="theEnd" />
		<endEvent id="theEnd" />
	</process>
	#1 Defining the mail service task
	#2 Declaring the recipient field
	#3 Declaring a subject
	#4 This mail has html content
	#5 Using the process variable

The mail service task is defined by adding an Activiti-specific attribute to a regular service task (#1). The email address is defined in the to field (#2) and the subject is defined with the subject attribute (#3). The email address that we send in this example is hardcoded in the BPMN 2.0 XML. In a loan request, we want this property to be flexible because it depends on who is filing for a loan, so we use the expression attribute to define the address:

<activiti:field name="to" expression="${loanApplication.customerName}" />

The mail we use has html content (#4). You also can see that, in the email task, you have access to process variables; in this case, we use the name process variable to make the email personal (#5).

You can now run the process within Eclipse, but we need a mail server so we can test the email service task. Listing 2 shows an elegant way of writing a unit test for this.

Listing 2 Testing a process definition with a email service task

public class MailTaskTest {
		@Rule
		public ActivitiRule activitiRule =
			new ActivitiRule("activiti.cfg-mem-mail.xml"); 				#1
		@Test
		@Deployment(resources={"chapter4/testSimpleTextMail.bpmn20.xml"})
		public void bookAvalaible() throws Exception {
			Wiser wiser = new Wiser(); 						#2
			wiser.setPort(25);
			wiser.start();
			activitiRule.getRuntimeService()
				.startProcessInstanceByKey("simpleEmailProcess");
			List messages = wiser.getMessages();
			assertEquals(1, messages.size()); 					#3
			WiserMessage message = messages.get(0);
			MimeMessage mimeMessage = message.getMimeMessage();
			assertEquals("Hello Miss Piggy!",
			mimeMessage.getHeader("Subject", null));
			wiser.stop();
		}
	}
	#1 Starts engine with mail client
	#2 Starts a test mail server
	#3 Did we receive 1 email?

Make sure that the mail server port in the activiti.cfg-mem-mail.xml file (#1) is configured for port 25. By default, Activiti expects the mail server to run on 5025, so we have to override the port by defining the following mail server.

<mail server=”localhost” port=”25″ />

The Activiti examples use a mail server that’s really great for unit testing and is called SubEtha SMTP (http://code.google.com/p/subethasmtp/). This mail server project provides a class named Wiser (#2), which can be used to start a mail server with just a few lines of code. And, when you want to check if an email has been sent to the mail server, you can use the getMessages method (#3). In this unit test, we validate if the subject of the email is the one we defined in the process definition of listing 1.

In addition to writing a unit test using the SubEtha mail server project, we can, of course, also use Apache James like we want to do for our loan request business process. You can use a similar unit test like the one we showed in code listing 2 but, instead of using SubEtha, you should start Apache James. To view the email, you can install an email client like, for example, Mozilla Thunderbird. James is using the default ports in the standard setup, so you only have to configure a Miss Piggy account running on localhost with port 25. The example email is shown in figure 3.

NOTE When you want to use the email task on the Tomcat distribution that Activiti ships with, you need to deploy two jars in the tomcat/lib directory; the mail.jar and the commons-mail.jar. Both the jars are available in the examples/activiti-engine-examples/libs-runtime directory of the Activiti distribution. Another important thing to remember is to set the port correctly in the activiti-cfg.xml file since, by default, it is listening on port 5025. You can find the Activiti configuration file that Tomcat uses in the tomcat/lib directory packaged in the activiti-cfg.jar.

What Activiti did with supplying the email task is demonstrate a showcase implementation of a custom and, therefore, not an official BPMN 2.0 task.

Summary

When the employees of the Loan Shark Company decide to not approve the loan request, an email is sent to inform the customer that the request has been denied.

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Speak Your Mind

*