Imixs Workflow ...the open source workflow technology for business applications

Workflow Engine

The Imixs Workflow Scheduler

The Imixs WorkflowScheduler is a TimerService EJB, which schedules Workflow Activities. A scheduled workflow activity can be defined by using the Imixs Modeler. If a workitem is in a stage with scheduled activities, the WorkflowScheduler will process this workitem automatically in a predefined interval. This is useful for automatic workflow tasks like reminder or escalation tasks.

The TimerService EJB

The WorkflowScheduler is declared by the interface and the implementation EJB.

public interface WorkflowScheduler {

    public void scheduleWorkflow(ItemCollection timerdescription)
            throws Exception;

    public void cancelScheduleWorkflow(String id) throws Exception;

    public ItemCollection findTimerDesciption(String id) throws Exception;
}

The Method "scheduleWorkflow" is for scheduling the TimerService. The method expects an ItemCollection with a description of the scheduled workflow (timerDescription).

The timerDescription has to support the following attributes:

  • datstart - Date Object datstop (Date Object)
  • numInterval - Integer Object (interval in seconds)
  • id - String - unique identifier for the schedule service

The attribute "id" should contain the EJB name. This is to avoid multiple instances of the TimerService, as only one scheduled workflow should run inside a WorkflowInstance. If a timer with the same id is already running the method stops this timer object first and reschedules the timer .

The following example shows how to initialize the scheduled WorkflowService :

// compute interval in miliseconds
int interval = (minutes + (hours * 60)) * 60*1000;
Calendar calNow=Calendar.getInstance();
Date startDate=calNow.getTime();
// Prepare Timer Object
ItemCollection timerDescription=new ItemCollection();
timerDescription.replaceItemValue("datstop", stopDate);
timerDescription.replaceItemValue("datstart", startDate);
timerDescription.replaceItemValue("numInterval", interval);
scheduledWorkflowService.scheduleWorkflow(timerDescription);
timerDescription=scheduledWorkflowService.findTimerDesciption(id);

The method findTimerDescription returns an ItemCollection with the description of a running ScheduleWorkflowService. This Collection contains the following additional information:

  • statusmessage - String with textual description of the current status
  • nextTimeout - Date object with the Time when the workflow will be next scheduled
  • timeRemaining - Long object with the time in milliseconds until the workflow will be next scheduled

Security & Deployment

The ScheduledWorkflowService EJB is embedded into the security concepts of the Imixs JEE Workflow. As the ScheduledWorkflowService needs full access rights to all workitems to perform a scheduled activity the EJB is annotated with the @RunAs declaration:

@DeclareRoles( { "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@Stateless
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
@Remote(org.imixs.workflow.jee.ejb.WorkflowScheduler.class)
public class WorkflowSchedulerBean implements WorkflowScheduler

This means that the WorkflowScheduler EJB should be deployed with necessary security role mappings. For Glassfish it is necessary to declare a principal-name which will be used by the EJB Container calling the @TimeOut method.

So we recommand to use the glassfish specific sun-application.xml deployment descriptor in the ear module. To declare a principal-name with manager access use the following example where Manfred is mapped to the Role "org.imixs.ACCESSLEVEL.MANAGER" in the realm "imixsrealm":

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-application PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Java EE Application 5.0//EN" "http://www.sun.com/software/appserver/dtds/sun-application_5_0-0.dtd">
<sun-application>
  
    <security-role-mapping>
        <role-name>org.imixs.ACCESSLEVEL.NOACCESS</role-name>
        <group-name>Noaccess</group-name>
    </security-role-mapping>

    <security-role-mapping>
        <role-name>org.imixs.ACCESSLEVEL.READERACCESS</role-name>
        <group-name>Reader</group-name>
    </security-role-mapping>

    <security-role-mapping>
        <role-name>org.imixs.ACCESSLEVEL.AUTHORACCESS</role-name>
        <group-name>Author</group-name>
    </security-role-mapping>

    <security-role-mapping>
        <role-name>org.imixs.ACCESSLEVEL.EDITORACCESS</role-name>
        <group-name>Editor</group-name>
    </security-role-mapping>

    <security-role-mapping>
        <role-name>org.imixs.ACCESSLEVEL.MANAGERACCESS</role-name>
        <group-name>Manager</group-name>
        <principal-name>Manfred</principal-name>
    </security-role-mapping>
    <realm>imixsrealm</realm>

</sun-application>

So in this case the TimerService will be performed by the user "Manfred".

Note:
Be careful to declare this role and principal-name with care and a setting which is reasonable in your server environment. For example use a reserved user account like "WorkflowScheduler" which is not used by persons in your organization.

The ejb-jar.xml

To get the WorkflowScheduler run successfully you also have to care about the right deployment of the EJB using the deployment descriptors.

Make sure that the EJB is defined in the ejb-jar.xml :

....
<session>            
<ejb-name>WorkflowSchedulerBean</ejb-name>       
    <ejb-class>    
                org.imixs.workflow.jee.ejb.WorkflowSchedulerBean     
    </ejb-class> 
   <session-type>Stateless</session-type>            
</session>

and also in the sun-ejb-jar.xml file:

.....
<ejb>         
   <ejb-name>WorkflowSchedulerBean</ejb-name>     
          <jndi-name>ejb/MyWorkflowScheduler</jndi-name>  
</ejb>

sun-ejb-jar.xml

Using the sun-ejb-jar.xml descriptor it is also necessary to add a principal user to the ejb declaration which will be associate to the @RunAss annotation.

If no principal is defined in sun-ejb-jar.xml, the application server uses a principal from the security-role-mapping. If there is only one principal associated with the role, that principal will be taken as the default run-as principal value. But if there is more than one principal associated with the role, you need to explicitly set the run-as principal in the sun-ejb-jar.xml.

The following example demonstrates setting the run-as principal in sun-ejb-jar.xml:

 ...
 <ejb>
 <ejb-name>WorkflowSchedulerBean</ejb-name>
 <jndi-name>
 ejb/MyWorkflowScheduler
 </jndi-name>
 <principal><name>Manfred</name></principal>
 </ejb>