ServerDeveloperGuide

From RunaWFE
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Server developer guide

RunaWFE Free Workflow System (BPMS) Version 4.5.0

© 2003 - 2015, Consulting Group Runa

© 2015 - 2024, "Process Technologies" Ltd, this document is available under GNU FDL license. RunaWFE Free is an open source system distributed under a LGPL license (http://www.gnu.org/licenses/lgpl.html).

# Introduction

# Basic components and used technologies

The following general architecture has been chosen for system. It's basically coherent with WfMC architectural proposal.

System components

  • System core
    • Contains a set of business processes definitions
    • Contains a set of running business processes instances
  • A component that assigns executors for tasks
  • Client
    • Task list. (A set of graphical forms, that contains the list of incoming tasks, sorting and filter configurations)
    • Form player (Renders forms that were developed in Developer Studio
    • Administrative interface
      • Shows the process state, allows to filter and stop processes
      • Allows to deploy/redeploy/remove process definitions
      • Allows to create/edit/remove users
      • Allows to set and configure permissions
    • Editor and substitutions assignment.
  • Developer Studio.
  • Graphical forms constructor (a part of Developer Studio).
  • Bot stations that contain bots. (Bots are applications of a particular type, they execute tasks just as regular system users)
  • Subsystems of permissions management (authorization and authentication)

# Programming platform and the development software used

The programming platform is J2EE.

Core technologies:

  • Hibernate 3.2 – ORM (allows easily to switch the system to other databases)
  • JAAS – authentication
  • EJB 3.0 stateless session beans – for remote interaction and transaction demarcation
  • JSP 2.0, Servlet 2.3, Struts 1.2 – for web client UI

And the development tools software is:

  1. Application server - JBOSS (http://www.jboss.org).
  2. IDE - Eclipse от IBM (http://www.eclipse.org).
  3. Version Control System – subversion (http://subversion.tigris.org/).
  4. Application Builder – maven.
  5. Database Server – the following DS are supported:
  6. Operating System — the following OSes are supported:
    • Windows (Server 2000-2008, XP, Vista, 7)
    • ALTLinux
    • Mandriva Linux
    • Fedora
    • Debian/Ubuntu

# Projects

Name Required for build Required for runtime Dependencies Description
wfe-alfresco no no runawfe-app Integration with Alfresco ECM
wfe-app yes yes wfe-ear, wfe-cactus-it Maven build support
wfe-appserver no no ? not used
wfe-bots yes yes wfe-service Bot subsystem
wfe-cactus-it yes no wfe-service Integration tests
wfe-core yes yes - Core components
wfe-ear yes yes wfe-service, wfe-bots, wfe-office, wfe-web Maven build: runawfe.ear
wfe-office yes no wfe-core Handlers for Word, Excel
wfe-remotebots yes no wfe-service Remote bot station (by RMI)
wfe-service yes yes wfe-core Public service API (EJB + WebServices)
wfe-web yes yes wfe-bots Web UI
wfe-webservice-client no no ? Java client classes based on WSDL with examples

# System architecture layers

Each subsystem contains several logical components that are relevant to each other. Each component consists of several layers.

The layers are:

  • delegate
  • service
  • logic
  • DAO
  • hibernate

# Delegate Layer

Delegate-classes are designed according to BusinessDelegate programming pattern and simplify access to the server side API. Client application interacts with system only via Delegate-classes. Delegates factory provides access to the Delegate-classes based on the configuration. Delegate classes are a part of client API.

The main Delegate-classes are:

    • AuthenticationServiceDelegate – contains methods for users authentication in the system (via entering login/password, Kerberos and etc).
    • AuthorizationServiceDelegate — contains methods for work with user permissions (assigning and verifying permissions for users etc).
    • BotServiceDelegate — contains methods for work with bots and bot stations.
    • ExecutorServiceDelegate — contains methods for work with executors. Allows to create/delete/edit executors and to add them to the groups.
    • ProfileServiceDelegate — contains methods for work with users profiles.
    • SubstitutionServiceDelegate — contains methods for substitution rules management.
    • SystemServiceDelegate — contains methods for user log in and log out.
    • DefinitionServiceDelegate — contains methods for work with process definitions.
    • ExecutionServiceDelegate — contains methods for work with process instances

All currently existing Delegate-classes implement the required functionality with the help of EJB (stateless session beans)

# Service Layer

Service Layer is a server side API that provides system access point. Delegate-classes addresses directly to this layer. Every Delegate has a corresponding Service interface (one-to-one correspondence). Currently all developed service classes and interfaces are oriented on EJB technology. Service classes implementations are Stateless Session Bean EJB, that support transactional calls via declaration and delegates the calls to the corresponding classes from Logic layer.

Thus, classes "Delegate – Service - Logic" form a communication between client and server.

# Logic Layer

Logic Levei is a system business logic implementation. This layer is connected with DAO layer classes to access persisted data.

# DAO Layer

DAO Layer contains classes and interfaces that provide access to the persisted data using datasource. Currently all DAO classes of the system are implemented with the help of ORM Hibernate.

# Hibernate Usage

Hibernate is an ORM (Object/Relational Mapping) implementation. It maps an object oriented architecture to the relational data structure. It allows to switch between a wide variety of RDBMS without changing the application code. Among supported DBMS are:

  • HSQLDB
  • Oracle
  • MS SQL Server
  • etc

Hibernate supports distributed transactions, automatically creates tables for new classes etc. All data manipulations within system is carried out only via Hibernate (except DB patches which uses native SQL).

# Database patches

See database versioning.

# Building from sources

Source code is available from https://github.com/processtech.

# Required software

You can build application either using command line or using any IDE. We are describing build process using Eclipse IDE (any version).

Apache Maven (>= 3.0.4) can be downloaded from [1]

  • add bin to system environment variable Path

# Application server

You can deploy runawfe.ear in any J2EE-compatible application server but there are 2 ready to use profiles: jboss4, jboss7.

Extenral dependencies in application server:

  • Data source
  • JMS queue queue/bpmMessages for message nodes

# Jboss 4.2.3

Build runawfe.ear using profile jboss4.

  1. Download RunaWFE Server, for example RunaWFE_Server4.0.6.zip and replace runawfe.ear in it.
  2. Download Jboss4.2.3 distributive and deploy JbossMessaging instead of JbossMQ using (instruction).

# Jboss 7.1.1

Build runawfe.ear using profile jboss7.

  1. Download RunaWFE Server, for example RunaWFE_Server7.4.1.0.zip and replace runawfe.ear in it.
  2. Download JbossAS 7.1.1 from http://www.jboss.org/jbossas.

In standalone.xml:

See as example File:Standalone.xml.

Note. In version 4.0.6 JMS queue has been renamed.

# Import projects

Import projects from https://github.com/processtech/runawfe-server.

# Install maven artifacts to local repository

Run ${wfe}/wfe-app/repository/add_dependencies.bat(sh) or instal them manually.

# Maven Build

Create build configuration as shown in figure

Maven.build.configuration.png

Set environment variables:

  • appserver sets application server type
  • deployment.dir sets folder for placing runawfe.ear

Execute it.

For command line use command like this.

mvn clean package -Dappserver=jboss7 -Ddeployment.dir=/path/to/dir

You can install artifacts into local repository by command.

mvn clean install -Dappserver=jboss7 -Dmaven.test.skip=true

# Extensions

# System functionality extension points

  • Handlers allows to extend process functionality
  • Variable formats allows to set type for variable value (including presentation in forms)
  • Organization functions are used for process swimlanes and executor substitutions
  • Substitution criterias allows to discriminate executor substitutions based on process context
  • Validators allows to validate user input data
  • Freemarker tags allows to customize task forms
  • Ajax commands allows to access to WFE Server through JavaScript (usually from task form)

# Developing extensions

Create new java maven project and add required dependencies (wfe-core, wfe-service).

Implement required functionality and build project as jar file.

Place jar file in the one the following destinations:

  • runawfe.ear!/lib
  • deploy directory (only for jboss4)
  • ${jboss.server.base.dir}/wfe.custom (only for jboss7)
  • ${jboss.server.base.dir}/${jboss.server.name}/wfe.custom (only for jboss4)

# Handlers

In order to do custom work in process elements "Action handler" and "Script task" can be used from palette. They are configured using action handler class implementation which implements ru.runa.wfe.extension.ActionHandler. Public default constructor is required. Configuration is set using method

setConfiguration(String)

Using @Autowired annotation you can inject any spring bean into handler.

You can also extend ru.runa.wfe.extension.handler.CommonHandler or ru.runa.wfe.extension.handler.CommonParamBasedHandler.

If exception occurs transaction is rolled back and process execution remains in the same place. In ru.runa.wfe.extension.TaskHandler a method onRollback is defined to work with non-transactional resources.

Limitations with action handlers:

  • there is no security context (i.e. User instance)
  • it is not a good solution to do in action handler long-running work

# Task handlers

Bot is automated task executor. Bot has login and password just like a human. Bot station is a subsystem which allows bot to login, acquire task list and execute tasks.

Each handler class should implement ru.runa.wfe.extension.TaskHandler.

# Decision handlers

Decision element (BPMN: exclusive gateway) from palette is used to decide which transition process execution follows. It is done using one of the ru.runa.wfe.extension.DecisionHandler implementation and configuration for it.

By default ru.runa.wfe.extension.decision.GroovyDecisionHandler is used.

# Using CommonParamBasedHandler

If you want to create action handler (or task handler) with fixed parameters you can extend in from ru.runa.wfe.extension.handler.CommonParamBasedHandler. This class encapsulates code for working with predefined XML format. Configuration example:

<?xml version="1.0" encoding="UTF-8"?>
<config>
 <input>
   <param name="typeName" variable="type name" />
   <param name="cause" variable="cause" />
   <param name="firmCode" value="111" />
 </input>
 <output>
   <param name="uuid" variable="object id" />
 </output>
</config>

Using Groovy

Read about groovy support.

# Organization functions

Organization functions are used for process swimlane initializers and in executor substitution rules.

Class should implement interface ru.runa.wfe.extension.OrgFunction.

List<? extends Executor> getExecutors(Object... parameters)

Register class in substitutions.xml to use it from web interface as organization function.

# Substitution criteria

Substitution criterion defines whether substitution should be applied for current task. Decision is done in process and task context.

Class should extend ru.runa.wfe.ss.SubstitutionCriteria.

Register class in substitution.criterias.xml to use it from web interface.

Variable formats

Read about variable formats.

# Validators

Validator class should extend ru.runa.wfe.validation.FieldValidator and be registered in validators.xml. In order to be available within Developer Studio it should be registered in plugin.xml as well.

Example:

public class OvertimeWorkRequestTimeCheck extends FieldValidator {
   @Override
   public void validate() {
       Date date = (Date) getFieldValue();
       if (date == null) {
           return;
       }
       boolean testMode = getVariableProvider().getValueNotNull(boolean.class, "test mode");
       if (testMode) {
           return;
       }
       Calendar calendar = CalendarUtil.dateToCalendar(date);
       if (calendar.before(Calendar.getInstance())) {
           addError("Only future dates are allowed");
           return;
       }
       CalendarUtil.setTimeFromCalendar(calendar, DemoProperties.getOvertimeWorkRequestMaximumStartTime());
       Utils.adjustCalendarForHolidaysInOvertimwWork(calendar);
       if (calendar.before(Calendar.getInstance())) {
           addError("Expired: " + CalendarUtil.formatDateTime(calendar));
       }
   }

}

# Freemarker tags

Tag class should extend ru.runa.wfe.commons.ftl.FreemarkerTag and registered in ftl.form.tags.xml. In order to be available in Developer Studio form editor register it in plugin.xml as well.

protected abstract Object executeTag() throws Exception;

During execution you can access User, PageContext, process variables and tag parameters. Return value can be of any type, you can use later it in form with freemarker expression language.

# Ajax freemarker tags

Extending from ru.runa.wfe.commons.ftl.AjaxFreemarkerTag facilitates ajax support in forms.

/**
 * Is invoked on first (static) page rendering
 * @return tag html
 */
protected abstract String renderRequest() throws Exception;
/**
 * Invoked on ajax request
 */
public void processAjaxRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

See ru.runa.wf.web.ftl.method.AjaxGroupMembersTag as example: in renderRequest it displays 2 combo boxes (group list and actor list) and processAjaxRequest is invoked when user change group in first combo.

# Ajax commands

Classes that extend ru.runa.wfe.commons.web.JsonAjaxCommand, (or implement ru.runa.wfe.commons.web.AjaxCommand) can be used from JavaScript calls, substantially in dynamic forms.

You an register custom command using:

  • file ajax.commands.xml by some name
  • spring context where bean id would be command name

Command name is used in ajax query.

Command example:

public class GetOrganizationNamesCommand extends JsonAjaxCommand {
   @Autowired
   private OrganizationDAO organizationDAO;
   @Override
   protected JSONAware execute(User user, HttpServletRequest request) throws Exception {
       String term = request.getParameter("term");
       if (term == null) {
           term = "";
       }
       List<Organization> organizations = organizationDAO.getAll();
       JSONArray array = new JSONArray();
       for (Organization organization : organizations) {
           if (organization.getName().startsWith(term)) {
               array.add(organization.getName());
           }
       }
       return array;
   }
}

Registration in wfe.custom.ajax.commands.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration xmlns="http://runa.ru/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://runa.ru/xml">
 <command name="getOrganizationNames" class="ru.runa.rkdemo.web.ajax.GetOrganizationNamesCommand" />
</configuration>

Using this command from task form JavaScript (autocomplete input)

$(document).ready(function() {
 $('#editLinkedLists').on("onRowAdded", function(event, rowIndex) {
  $("input[name='orgnames["+rowIndex+"]']").autocomplete( {
   delay: 300,
   minLength: 0,
   source: "/wfe/ajaxcmd?command=getOrganizationNames"
  });
  $("input[name='orgnames["+rowIndex+"]']").focus(function() {
   $(this).autocomplete("search", $(this).val());
  });
 });
});