Activiti ‘Hello world’ on play!

Previously, i told about my experiences with play module/plugin development. I tried to point out how it was easy to extend the framework to your needs. A primitive activiti plugin was the product of that effort, and i said there will be a simple application using this. Here goes.

I picked the “Financial Report” example from 10 minute tutorial part of the activiti documentation because it seems the easiest way of demonstrating that it works. The BPMN file -which is used to define the business process- can be obtained from the site.

The use case is straightfoward: we have a company, let’s call it BPMCorp. In BPMCorp, a financial report needs to be written every month for the company shareholders. This is the responsibility of the accountancy department. When the report is finished, one of the members of the upper management needs to approve the document before it is sent to all the shareholders.

Process simply composes of two user actions (emphasized). It also mentions user groups (accountancy department and upper management) but i did not include them in my example in order to keep things simple. However, i used Secure module for user identification. Interface will be composed of three lists; one for processes deployed (registered) in activiti, one for tasks to start and another one for tasks of currently logged in user.

Since there is only one process definition deployed, first list will show only one item. A user will start the process by clicking [New] link next to it, and activiti will create a task per our process definition which will be listed in the second list. This list may contain arbitrary number of tasks from different process instances, which means there may be more than one instance of the financial report process at any given time. The user will start working on the task by clicking [Start] next to task. Now the task will move into the next list. It will wait there until the task is finished. User may logout and log back in to see his/her tasks waiting to be [Finish]ed. All of that information will be stored in activiti.

Other users may work on whatever tasks they should be working too.

Enough crappy screenshots. The code is simply one template and one controller to show lists and back actions.

#{extends 'main.html' /}
#{set title:'Home' /}

Welcome ${user}! <a href="@{Secure.logout()}">Logout</a>
<h3>Processes</h3>
#{list items:pdl, as:'pd'}
    [<a href="@{Application.start(pd.getId())}">New</a>]
    ${pd.getName()}<br/>
#{/list}
<h3>Tasks</h3>
#{list items:utl, as:'ut'}
    [<a href="@{Application.claim(ut.getId())}">Start</a>]
    ${ut.getName()}<br/>
#{/list}
<h3>My Tasks</h3>
#{list items:atl, as:'at'}
    [<a href="@{Application.complete(at.getId())}">Finish</a>]
    ${at.getName()}<br/>
#{/list}
@With(Secure.class)
public class Application extends Controller {
	
    @Inject static ProcessEngine pe;

    public static void index() {
        String user = Security.connected();
        List pdl = pe.getRepositoryService().
                createProcessDefinitionQuery().list();

        List utl = pe.getTaskService().createTaskQuery().
                taskUnnassigned().list();

    	List atl = pe.getTaskService().createTaskQuery().
                taskAssignee(Security.connected()).list();
        render(user, pdl, utl, atl);
    }
    
    public static void start(String pid){
    	String pdid = pe.getRepositoryService().
                createProcessDefinitionQuery().
                processDefinitionId(pid).
                singleResult().
                getId();
        pe.getRuntimeService().startProcessInstanceById(pdid);
        index();
    }
    
    public static void claim(String tid){
        pe.getTaskService().claim(tid, Security.connected());
        index();
    }

    public static void complete(String tid){
        pe.getTaskService().complete(tid);
        index();
    }
}

There is only one piece missing in this simple example: how did i deploy my process definition in the first place? Well, it is the dirtiest hack possible. I put it into the plugin where i initialized ProcessEngine. There are many ways to deploy a process definition into activiti and i didn’t want to get into the specifics. I used a mem database for the same reason, so none of these were persistent. I tried to see if the plugin would actually work and it did! On the other hand, if i wanted something in production i know it is a matter of configuration.

I said all i can about play’s plugin system in the previous post, it is great. But since it was about initializing activiti i didn’t say anything about it. AFAICT, it is one of the few libraries/frameworks that delivers what it advertises. It is light-weight, fast and simple. They say a BPM engine should be working in every Java environment, and this ‘helloworld’ is one example. API is clean, well documented and easy to work with. As a developer who correlates BPM engines to application servers that cannot start in under a minute, i am really pleased with what i was able to achieve. Overall experience with activiti is simply great.

Notes

  1. trampoline3n reblogged this from agaoglu
  2. istoselidon9t reblogged this from agaoglu
  3. ntktgtym43 reblogged this from agaoglu
  4. gustavoarjones reblogged this from agaoglu
  5. agaoglu posted this