BPM Workflow with Camunda BPM

Hi all,In my last post we have seen how to orchestrate BPEL process,but today we are going to see how we can develop a BPMN workflow using Camunda.This is also part of SOA stack,in my upcoming posts we will discuss about SOA technologies .

Briefly the below is the BPM work flow
Untitled

Please install the BPM modeling plugin and tools, also the Camunda BPM suite from the below link
download BPM modeling tools and BPM Suite

once we have all the software are in place, lets start our tutorial.
create a maven project and put all the dependencies in pom.xml as shown below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spark.camunda.bpm.process</groupId>
	<artifactId>TestBpmProcess</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>TestBpmProcess</name>
	<description>TestBpmProcess</description>

	<properties>
		<jdk.version>1.6</jdk.version>
	</properties>

	<dependencies>
		<!-- camunda engine dependency -->
		<dependency>
			<groupId>org.camunda.bpm</groupId>
			<artifactId>camunda-engine</artifactId>
			<version>7.1.0-Final</version>
			<scope>provided</scope>
		</dependency>

		<!-- camunda cdi beans -->
		<!-- <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-engine-cdi</artifactId> 
			<version>7.1.0-Final</version> </dependency> -->

		<!-- provides a default EjbProcessApplication -->
		<!-- <dependency> <groupId>org.camunda.bpm.javaee</groupId> <artifactId>camunda-ejb-client</artifactId> 
			<version>7.1.0-Final</version> </dependency> -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		
		<!-- Mysql dependency -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.6</version>
		</dependency>


		<!-- jars for email trigger -->
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.7</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.extras</groupId>
			<artifactId>javaee</artifactId>
			<version>3.1.1</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

once we have the dependency ready, lets start coding our logic, lets start writing the logic for initial task form as follows.


<form class="form-horizontal">
	<div class="control-group">
		<label class="control-label">Customer ID</label>
		<div class="controls">
			<input form-field type="string" name="customerId" />
		</div>
	</div>
	<div class="control-group">
		<label class="control-label">Department</label>
		<div class="controls">
			<input form-field type="string" name="deptName" />
		</div>
	</div>
	<div class="control-group">
		<label class="control-label">Amount</label>
		<div class="controls">
			<input form-field type="number" name="amount" />
		</div>
	</div>
</form>

now lets map this task form to the start task of our BPM process as shown below.
request-loan

Now lets write a class to process the request and assign it to the “ProcessRequest” “ServiceTask” as shown below.

/**
 * 
 */
package com.spark.camunda.bpm.loanapproval;

import java.util.Map;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

/**
 * @author Sony
 * 
 */
public class ProcessRequestDeligate implements JavaDelegate {

	@Override
	public void execute(DelegateExecution delegateExecution) throws Exception {

		Map<String, Object> variables = delegateExecution.getVariables();
		if ("dept1".equalsIgnoreCase((String) variables.get("deptName"))) {
			delegateExecution.setVariable("deptName", (String) variables.get("deptName"));
			
		} else if ("dept2".equalsIgnoreCase((String) variables.get("deptName"))) {
			delegateExecution.setVariable("deptName", (String) variables.get("deptName"));
		}
	}

}

process-req

once done we need to decide the conditional flow for the exclusive gateway. this is shown below.

cond1

cond2

once the request is forwarded to human task based on the condition. Here the condition is the loan approval for a particular department(dept1,dept2) based on this the manager will approve the request for the respective department. lets write the task form for manager to approve the request as below.


<form class="form-horizontal">
	<div class="control-group">
		<label class="control-label">Customer ID</label>
		<div class="controls">
			<input form-field type="string" name="customerId" readonly="true" />
		</div>
	</div>
	<div class="control-group">
		<label class="control-label">Amount</label>
		<div class="controls">
			<input form-field type="number" name="amount" />
		</div>
	</div>
</form>

once the manager approves the loan request the requst gets persisted into database and a event mail gets triggered to the customer. please find the below is the persistence task logic

/**
 * 
 */
package com.spark.camunda.bpm.loanapproval;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

import com.spark.camunda.bpm.factory.SqlConnectionFactory;

/**
 * @author Sony
 * 
 */
public class PersistenceRequestDeligate implements JavaDelegate {

	@Override
	public void execute(DelegateExecution delegateExecution) throws Exception {

		SqlConnectionFactory connectionFactory = SqlConnectionFactory
				.getFactoryObject();
		Connection connection = connectionFactory.getSqlConnection();
		PreparedStatement preparedStatement = null;
		String sql = "insert into loanprocess(customer_id,amount) values (?,?)";
		preparedStatement = connection.prepareStatement(sql);
		preparedStatement.setString(1,
				delegateExecution.getVariable("customerId").toString());
		preparedStatement.setString(2, delegateExecution.getVariable("amount")
				.toString());
		preparedStatement.executeUpdate();

		preparedStatement.close();
		connection.close();
	}

}

please find the below is the event mail triggering logic

/**
 * 
 */
package com.spark.camunda.bpm.loanapproval;

import java.util.Properties;
import java.util.logging.Logger;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

/**
 * @author Sony
 * 
 */
public class SendLoanApprovalConfirmation implements JavaDelegate {

	private final static Logger LOGGER = Logger.getLogger("SendLoanApprovalConfirmation");
	
	@Override
	public void execute(DelegateExecution delegateExecution) throws Exception {

		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.port", "465");

		Session session = Session.getDefaultInstance(props,
				new javax.mail.Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication("xxx@gmail.com",
								"password");
					}
				});

		try {

			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress("xxx@gmail.com"));
			message.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse("xxx@gmail.com"));
			message.setSubject("Loan Approval from John");
			message.setText("Dear Applicant your loan has got approved,"
					+ "\n\n please collect your check for the requested amount of"+delegateExecution.getVariable("amount"));

			Transport.send(message);

			LOGGER.info("processing mail sent to customer ID:"+delegateExecution.getVariable("customerId"));

		} catch (MessagingException e) {
			throw new RuntimeException(e);
		}
	}

}

please run mvn clean install package, now a war gets generated. Please deploy this war into JBoss Application server deployments folder and now start the camunda cockpit application and camunda tasklist application as shown below.

cockpit

create an instance by logging with demo/demo into camunda/tasklist application as shown below, since the entered details are for dept1 the approval goes to “john”(manager of dept1).

loanapproval

now go and see the camunda/cockpit it shows the present status of the BPM work flow as shown below.
waitingforapproval

Now john needs to login into task list to approve his assigned tasks, once he approves a automated mai is triggered to the applicant as shown below.
approvebyjohn

thats all folks now you are ready to code your own BPMN processes using Camunda BPM suit and JBoss App Server.
Happy Camunda BPMN WorkFlows 🙂 Happy SOA 🙂

jBPM Introduction

jBPM is a flexible Business Process Management (BPM) Suite. It’s light-weight, fully open-source (distributed under Apache license) and written in Java. It allows you to model, execute and monitor business processes, throughout their life cycle.

A business process allows you to model your business goals by describing the steps that need to be executed to achieve that goal and the order, using a flow chart. This greatly improves the visibility and agility of your business logic. jBPM focuses on executable business process, which are business processes that contain enough detail so they can actually be executed on a BPM engine. Executable business processes bridge the gap between business users and developers as they are higher-level and use domain-specific concepts that are understood by business users but can also be executed directly.

fig:1

The core of jBPM is a light-weight, extensible workflow engine written in pure Java that allows you to execute business processes using the latest BPMN 2.0 specification. It can run in any Java environment, embedded in your application or as a service.

On top of the core engine, a lot of features and tools are offered to support business processes throughout their entire life cycle:

1. Eclipse-based and web-based editor to support the graphical creation of your business processes (drag and drop)
2. Pluggable persistence and transactions based on JPA / JTA
3. Pluggable human task service based on WS-HumanTask for including tasks that need to be performed by human actors
4. Management console supporting process instance management, task lists and task form management, and reporting
5. Optional process repository to deploy your process (and other related knowledge)
6. History logging (for querying / monitoring / analysis)
7. Integration with Seam, Spring, OSGi, etc.

BPM makes the bridge between business analysts, developers and end users, by offering process management features and tools in a way that both business users and developers like it. Domain-specific nodes can be plugged into the palette, making the processes more easily understood by business users.

jBPM supports adaptive and dynamic processes that require flexibility to model complex, real-life situations that cannot easily be described using a rigid process. We bring control back to the end users by allowing them to control which parts of the process should be executed, to dynamically deviate from the process, etc.

jBPM is also not just an isolated process engine. Complex business logic can be modeled as a combination of business processes with business rules and complex event processing. jBPM can be combined with the Drools project to support one unified environment that integrates these paradigms where you model your business logic as a combination of processes, rules and events.

Apart from the core engine itself, there are quite a few additional (optional) components that you can use, like an Eclipse-based or web-based designer and a management console.

jBPM Overview:

fig:2

wait for my next posts.
Credit: article directly taken from JBoss Documents.

Happy Coding , Happy SOA and jBPM 🙂