Difference between revisions of "ServerDeveloperGuide"
doc>Kaja |
m (1 revision imported) |
Latest revision as of 06:37, 23 November 2020
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:
- Application server - JBOSS (http://www.jboss.org).
- IDE - Eclipse от IBM (http://www.eclipse.org).
- Version Control System – subversion (http://subversion.tigris.org/).
- Application Builder – maven.
- Database Server – the following DS are supported:
- MS SQL Server (http://www.microsoft.com/sql/evaluation/default.mspx)
- HSSQLDB (http://hsqldb.org)
- Oracle (http://www.oracle.com)
- Postgres (http://postgresql.com)
- 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.
- Download RunaWFE Server, for example RunaWFE_Server4.0.6.zip and replace runawfe.ear in it.
- Download Jboss4.2.3 distributive and deploy JbossMessaging instead of JbossMQ using (instruction).
# Jboss 7.1.1
Build runawfe.ear using profile jboss7.
- Download RunaWFE Server, for example RunaWFE_Server7.4.1.0.zip and replace runawfe.ear in it.
- Download JbossAS 7.1.1 from http://www.jboss.org/jbossas.
In standalone.xml:
- enable JMS (hornet-mq) and configure JMS queue
- set request encoding to UTF-8
- extend deployment time (optional)
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
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
# 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
# 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()); }); }); });