|
Key
This line was removed.
This word was removed. This word was added.
This line was added.
|
Changes (151)
View Page History{warning}This version must be installed on Petals ESB 5.0.2+{warning}
{multi-excerpt-include:Petals-SE-Activiti|name=features|nopanel=true} {multi-excerpt-include:Petals-SE-Flowable|name=features|nopanel=true}
{column}
h1. Introduction
The version 1.1.0+ of the component embeds the BPMN 2.0 engine "Activiti" v5.22.0-PETALS-0 (official v5.22.0 completed with few contributions of Petals team). So, Activiti extensions can be used at the runtime level.
The version 1.0.0+ of the component embeds the BPMN 2.0 engine "Flowable" v5.23.0. So, Flowable extensions can be used at the runtime level.
h1. System requirements
The Petals SE Activiti Flowable *MUST* be deployed on a container running with a *Java Development Kit* (JDK), not a Java Runtime Environment !!
h1. Using the mode "service"
h3. Creating the service contract
The SE Activiti Flowable provides a service with several operation for a process definition. A WSDL is associated to this service. This WSDL can be written freely. The user can use its own namespace, its own names, ... It is only constraint by the following rules:
* the operations of the binding section *are annotated* to link them to the supported operations of the process definition (create an instance of the process definition, complete the current task of the process instance, ...)
* the parameters of the operation *are annotated* to retrieve the right values to transmit to the BPMN engine,
* the output and fault of the operations *are annotated* to build the service output from the result of the operation on the BPMN engine side.
* the parameters of the operation *are annotated* to retrieve the right values to transmit to the BPMN engine,
* the output and fault of the operations *are annotated* to build the service output from the result of the operation on the BPMN engine side.
{tip}For a unit test purpose, an extension of JUnit is available to validate your WSDL not only in a our WSDL point of view, but also in a SE Activiti Flowable point of view. See chapter "[Unit testing|#Unit_Testing]".{tip}
h4. Identifying operations
The mapping between operations of the WSDL and operations supported by the BPMN 2.0 engine embedded in the SE Activiti Flowable is declared using a dedicated binding. The binding "BPMN2" "Flowable" is done adding the element {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}operation}} {{\{http://petals.ow2.org/se/flowable/annotations/1.0}operation}} to the element operation of the binding. Its attribute *{{action}}* defines the operation that will be executed on the process engine according to the following values:
|| Value of {{action}} || Operation executed on the process engine ||
| {{startEvent}} | Create a new instance of the process. See [Associating an operation to the creation of an process definition instance|#associating_startEvent] for more information on this operation. |
| {{startEvent}} | Create a new instance of the process. See [Associating an operation to the creation of an process definition instance|#associating_startEvent] for more information on this operation. |
Expected input parameters are declared using dedicated annotation according to the operation:
|| Value of the attribute {{action}} of the annotation {{bpmn:operation}} {{flowable:operation}} || Operation executed on the process engine ||
| {{startEvent}} | Expected input parameters are:
* the process identifier,
* the process identifier,
See [Associating an operation to the completion of a process instance task|#associating_userTask] for more information on the declaration of these parameters. |
Variables are identified by the annotation adding the element {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}variable}}: {{\{http://petals.ow2.org/se/flowable/annotations/1.0}variable}}:
* its attribute *{{name}}* defines the variable name used in the process definition.
* its content defines the value to set to the variable using an XPath expression.
{code}
* its content defines the value to set to the variable using an XPath expression.
{code}
<bpmn:variable <flowable:variable name="numberOfDays">
/*[local-name()='demande']/*[local-name()='nbJourDde']
</bpmn:variable> </flowable:variable>
{code}
See operation details to know if variables can be set.
See operation details to know if variables can be set.
No extra check is done by the SE Activiti Flowable about the compliance of the variable with the process definition.
{color:red}*TODO. Les types ?; les arborescences*{color}
h4. Identifying output parameters of operations
Output parameters of the BPMN 2.0 engine API operation can not be mapped to the output reply of the service operation using a simple XPath expression as for input parameters. An XSL style-sheet is required to generated the full output reply. It is identified using the annotation adding the element {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}output}} {{\{http://petals.ow2.org/se/flowable/annotations/1.0}output}} that contains the XSL style-sheet name. The XSL style-sheet is read from the classloader or through a file relative to the root directory of the service unit. The XSL style-sheets are mainly located in the service-units, they can also be packaged as a shared library.
According to the operation executed by the BPMN 2.0 engine, its output parameters are transmitted to the XSL style-sheet through XSL parameters. You will use these XSL parameters to generate your service reply from your service request payload. See operation details to know the available XSL parameters.
When an error occurs on the BPMN engine side, this error can be returned as business fault or technical error. The business faults are declared into the WSDL of the service.
The mapping of an error of the BPMN engine to a business fault is defined using the annotation {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}fault}} {{\{http://petals.ow2.org/se/flowable/annotations/1.0}fault}} set as child element of the WSDL fault. The attribute {{name}} will contain a key word identifying the error on the BPMN engine. And the content value is the name of the XSLT style-sheet to use to generate the business fault.
The XSL style-sheet is read from the classloader or through a file relative to the root directory of the service unit. The XSL style-sheets are mainly located in the service-units, they can also be packaged as a shared library.
h4. Associating an operation to the creation of an process instance
The operation creating instances of process definition is identified by the value *{{startEvent}}* set on the attribute {{action}} of the annotation {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}operation}}. {{\{http://petals.ow2.org/se/flowable/annotations/1.0}operation}}. As your service unit can include several process definition, you need to clarify the process definition to use to create the process instance using the attribute *{{processDefinitionId}}*. As a process definition can include several start events, the right start event to use to create the new process instance is clarified with attributes:
* *{{none-start-event-id}}* for none start event,
* or *{{start-event-message-name}}* for message start event.
This operation accepts variables and requires the following input parameters:
* or *{{start-event-message-name}}* for message start event.
This operation accepts variables and requires the following input parameters:
* user identifier, declared using the annotation {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}userId}} {{\{http://petals.ow2.org/se/flowable/annotations/1.0}userId}} containing an XPath expression that is applied on incoming XML payload to get the value of the user identifier to use on the BPMN engine side.
The XSL parameters available to generate the service output reply are:
|| XSL parameter name || Type || Description ||
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/special}processInstanceId \{http://petals.ow2.org/se/flowable/output-params/1.0/special}processInstanceId | String | Identifier of the process instance created |
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/special}userId \{http://petals.ow2.org/se/flowable/output-params/1.0/special}userId | String | The user identifier used to create the process instance |
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/process-instance}variable-name \{http://petals.ow2.org/se/flowable/output-params/1.0/process-instance}variable-name | String | Process instance variables. <variable-name> is the name of a process instance variable. |
On this operation, no error thrown by the BPMN engine can be mapped to business fault.
{code:title=WSDL mapping sample}
<wsdl:binding name="Order" xmlns:bpmn="http://petals.ow2.org/se/bpmn2.0/1.0"> xmlns:flowable="http://petals.ow2.org/se/bpmn/annotations/1.0">
<wsdl:operation name="newOrder" type="...">
<bpmn:operation <flowable:operation processDefinitionId="order" action="startEvent" start-event-message-name="newOrder"/>
<bpmn:userId>/*[local-name()='newOrderRequest']/*[local-name()='userName']</bpmn:userId> <flowable:userId>/*[local-name()='newOrderRequest']/*[local-name()='userName']</flowable:userId>
<bpmn:variable <flowable:variable name="address">
/*[local-name()='newOrderRequest']/*[local-name()='address']
</bpmn:variable> </flowable:variable>
<bpmn:output>newOrderOutput.xsl</bpmn:output> <flowable:output>newOrderOutput.xsl</flowable:output>
<wsdl:input/>
<wsdl:output/>
<wsdl:output/>
h4. Associating an operation to the completion of a process instance task
The operation completing a task of a process instance is identified by the value *{{userTask}}* set on the attribute {{action}} of the annotation {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}operation}}. {{\{http://petals.ow2.org/se/flowable/annotations/1.0}operation}}. To guarantee that the expected user task is the right one, its identifier is clarified with the attribute *{{user-task-id}}*.
This operation accepts variables and requires the following input parameters:
* process instance identifier, declared using the annotation {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}processId}} {{\{http://petals.ow2.org/se/flowable/annotations/1.0}processId}} containing an XPath expression that is applied on incoming XML payload to get the value of the process instance identifier to use on the BPMN engine side.
* user identifier, declared using the annotation {{\{http://petals.ow2.org/se/bpmn/annotations/1.0}userId}} {{\{http://petals.ow2.org/se/flowable/annotations/1.0}userId}} containing an XPath expression that is applied on incoming XML payload to get the value of the user identifier to use on the BPMN engine side.
Note: The completion status of the task is a variable and so it takes any form.
The XSL parameters available to generate the service output reply are:
|| XSL parameter name || Type || Description ||
|| XSL parameter name || Type || Description ||
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/special}processInstanceId \{http://petals.ow2.org/se/flowable/output-params/1.0/special}processInstanceId | String | Identifier of the process instance created |
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/special}userId \{http://petals.ow2.org/se/flowable/output-params/1.0/special}userId | String | The user identifier used to create the process instance |
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/process-instance}variable-name \{http://petals.ow2.org/se/flowable/output-params/1.0/process-instance}variable-name | String | Process instance variables. <variable-name> is the name of a process instance variable. |
| \{http://petals.ow2.org/se/bpmn/output-params/1.0/task}variable-name \{http://petals.ow2.org/se/flowable/output-params/1.0/task}variable-name | String | Task local variables. <variable-name> is the name of a task local variable. |
The following errors thrown by the BPMN engine can be mapped to business fault:
|| Error || Description || XSL parameters ||
| {{TaskCompletedException}} | The associated user task is already completed | * process instance identifier: \{http://petals.ow2.org/se/bpmn/faults/1.0}processInstanceId \{http://petals.ow2.org/se/flowable/faults/1.0}processInstanceId
* task identifier: \{http://petals.ow2.org/se/bpmn/faults/1.0}taskId \{http://petals.ow2.org/se/flowable/faults/1.0}taskId |
| {{ProcessInstanceNotFoundException}} | No active process instance found for the given process instance identifier | process instance identifier: \{http://petals.ow2.org/se/bpmn/faults/1.0}processInstanceId \{http://petals.ow2.org/se/flowable/faults/1.0}processInstanceId |
| {{UnexpectedUserException}} | The task to complete is assigned to another user identifier | * process instance identifier: {{\{http://petals.ow2.org/se/bpmn/faults/1.0}processInstanceId}} {{\{http://petals.ow2.org/se/flowable/faults/1.0}processInstanceId}}
* task identifier: \{http://petals.ow2.org/se/bpmn/faults/1.0}taskId \{http://petals.ow2.org/se/flowable/faults/1.0}taskId
* user identifier: \{http://petals.ow2.org/se/bpmn/faults/1.0}userId \{http://petals.ow2.org/se/flowable/faults/1.0}userId |
A such operation is defined for each task of the process definition to complete. {color:red}*C'est le cas d'un service par tache à terminer. Essayer de mieux expliquer.*{color}.
{code:title=WSDL mapping sample}
<wsdl:binding name="Order" xmlns:bpmn="http://petals.ow2.org/se/bpmn/annotations/1.0" xmlns:flowable="http://petals.ow2.org/se/flowable/annotations/1.0" >
<wsdl:operation name="validOrder">
<bpmn:operation <flowable:operation processDefinitionId="order" action="userTask" user-task-id="validOrder"/>
<bpmn:processId>/*[local-name()='validOrderRequest']/*[local-name()='orderId']</bpmn:processId> <flowable:processId>/*[local-name()='validOrderRequest']/*[local-name()='orderId']</flowable:processId>
<bpmn:userId>/*[local-name()='validOrderRequest']/*[local-name()='userName']</bpmn:userId> <flowable:userId>/*[local-name()='validOrderRequest']/*[local-name()='userName']</flowable:userId>
<bpmn:variable <flowable:variable name="validationApproved">
/*[local-name()='validOrderRequest']/*[local-name()='isValidated']
</bpmn:variable> </flowable:variable>
<bpmn:variable <flowable:variable name="creditCardNumber">
/*[local-name()='validOrderRequest']/*[local-name()='creditCardNumber']
</bpmn:variable> </flowable:variable>
<bpmn:output>validOrderOutput.xsl</bpmn:output> <flowable:output>validOrderOutput.xsl</flowable:output>
<wsdl:input/>
<wsdl:output/>
<wsdl:output/>
The operation retrieving process instances is identified by the value *{{retrieveProcInst}}* set on the attribute {{action}}:
{code}
{code}
<wsdl:binding name="Order" xmlns:bpmn="http://petals.ow2.org/se/bpmn/annotations/1.0"> xmlns:flowable="http://petals.ow2.org/se/flowable/annotations/1.0">
<wsdl:operation name="searchOrder" type="...">
<bpmn:operation <flowable:operation action="retrieveProcInst" />
<bpmn:input-parameter <flowable:input-parameter name="isActive" value="/searchOrderRequest/isInProgress" />
<bpmn:input-parameter <flowable:input-parameter name="responsibleUser" value="/searchOrderRequest/responsibleUser" />
<bpmn:input-parameter <flowable:input-parameter name="responsibleGroup" value="/searchOrderRequest/responsibleGroup" />
<bpmn:output>searchOrderOutput.xsl</bpmn:output> <flowable:output>searchOrderOutput.xsl</flowable:output>
<wsdl:input/>
<wsdl:output/>
<wsdl:output/>
<petalsCDK:wsdl>vacationService.wsdl</petalsCDK:wsdl>
<petals-se-activitibpmn:tenant_id>my-tenant</petals-se-activitibpmn:tenant_id> <petals-se-flowable:tenant_id>my-tenant</petals-se-flowable:tenant_id>
<petals-se-activitibpmn:category_id>samples</petals-se-activitibpmn:category_id> <petals-se-flowable:category_id>samples</petals-se-flowable:category_id>
<petals-se-activitibpmn:process_file1>vacationRequest.bpmn20.xml</petals-se-activitibpmn:process_file1> <petals-se-flowable:process_file1>vacationRequest.bpmn20.xml</petals-se-flowable:process_file1>
<petals-se-activitibpmn:version1>1</petals-se-activitibpmn:version1> <petals-se-flowable:version1>1</petals-se-flowable:version1>
</jbi:provides>
{code}
{note}Only one section '{{provides}}' is accepted by the Petals SE Activiti.{note} Flowable.{note}
If your business process includes service tasks to invoke service providers, you can add a section '{{consumes}}' for each one to drive more precisely the invocation:
<jbi:provides ...>
...
...
<petals-se-activitibpmn:process_file1>vacationRequest.bpmn20.xml</petals-se-activitibpmn:process_file1> <petals-se-flowable:process_file1>vacationRequest.bpmn20.xml</petals-se-flowable:process_file1>
<petals-se-activitibpmn:version1>1</petals-se-activitibpmn:version1> <petals-se-flowable:version1>1</petals-se-flowable:version1>
</jbi:provides>
|| Parameter || Description || Default || Required ||
| tenant_id | Tenant identifier. As the [multitenancy is supported|http://www.activiti.org/userguide/#advanced.tenancy]], supported|http://www.flowable.org/docs/userguide/index.html#advanced.tenancy], such an identifier is required. | {{myTenant}} | No |
| category_id | Deployment category identifier. For example to group business processes. | {{myCategory}} | No |
| process_file | Name of the process definition file into the service unit (relative to the root of the service unit). \\
| process_file | Name of the process definition file into the service unit (relative to the root of the service unit). \\
h2. Deploying a service unit
When deploying the service unit on the SE Activiti, Flowable, the embedded process definition is automatically deployed into the BPMN 2.0 engine, and the associated services are registered.
{note}When a Petals ESB node restarts, all service units previously deployed are redeployed. So if a process definition is already registered in the BPMN 2.0 engine, its registration is skipped without any message.{note}
h2. Undeploying a service unit
When undeploying a service unit from the SE Activiti, Flowable, the embedded process definition is deregistered from the BPMN 2.0 engine, and the associated services are unregistered.
{color:red}Que faire si il y a encore de process instances en cours ?{color}
h1. Invoking Petals service providers from Activiti Flowable process
The Petals service providers can be invoked natively from Activiti Flowable process using a '{{ServiceTask}}' into your process definition through three steps:
# import the service contract of the Petals service provider into your service-unit project,
# define the Petals service provider address,
# define the Petals service provider address,
<wsdl:service name="notifyVacationService">
<wsdl:port name="autogenerate" binding="notifyService:notifyVacationBinding">
<wsdl:port name="autogenerate" binding="notifyService:notifyVacationBinding">
<soap:address location="petals:///{http://petals.ow2.org/samples/se-bpmn/notifyVacationService}notifyVacation" location="petals:///{http://petals.ow2.org/samples/se-flowable/notifyVacationService}notifyVacation" />
</wsdl:port>
</wsdl:service>
</wsdl:service>
Once a '{{ServiceTask}}' has been added to your process, you will configure it as following to invoke the right Petals service provider:
# First, import the Petals service provider contract into the Activiti Flowable process definition:
{code:xml}
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" ...>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" ...>
h1. Using the mode "integration"
The mode "integration" provides different services to interact directly with the BPMN 2.0 engine embedded in the SE Activiti. Flowable. It goes back over the BPMN 2.0 engine API. Available services are:
|| Interface name || Service name || Description ||
| {{ProcessInstances}} | {{ProcessInstancesService}} | To manage process instances |
| {{Task}} | {{TaskService}} | To manage tasks of process instances |
| {{ProcessInstances}} | {{ProcessInstancesService}} | To manage process instances |
| {{Task}} | {{TaskService}} | To manage tasks of process instances |
{tip}The namespace of interface name and service name is {{http://petals.ow2.org/components/activiti/generic/1.0}}{tip} {{http://petals.ow2.org/components/flowable/generic/1.0}}{tip}
h2. The service "ProcessInstanceService"
h1. Identity service integration
The Activiti Flowable engine requires an entity service in charge of managing users and groups. It is required by the user tasks that are assigned to users or groups.
Once you have selected your entity service implementation, just configure it (the implementation) at component level through the parameters {{engine-identity-service-class-name}} and {{engine-identity-service-config-file}}. By default, the Petals SE Activiti Flowable uses a based-file entity service.
Available entity services are:
h2. File-based entity service
This entity service is a demonstration entity service, that's why it is embedded into the Petals SE Activiti. Flowable. It is based on two files, one containing the users, another containing the group definitions.
h3. Configuration
| {{groups-file}} | File name of the file containing the user group declarations. If it is an existing absolute file name, the file is read as a file from the filesystem, otherwise it is read as a resource from the component classloader. | Yes |
The entity service includes a default configuration used when the entity service configuration file is not set at the component level. This default configuration is inspired of Activiti Flowable itself defining users and groups as mentioned as examples below in file formats
h3. File formats
h2. Write your own entity service
You can write your own entity service. It will be available as a shared library that you will configure to be used by the Petals SE Activiti. Flowable.
To implement it, just create a class implementing the interface {{org.ow2.petals.activitibpmn.identity.IdentityService}}. {{org.ow2.petals.flowable.identity.IdentityService}}. You can find an example [here|https://github.com/petalslink/petals-se-activiti/blob/petals-se-activiti-0.5.0/src/main/java/org/ow2/petals/activitibpmn/identity/file/FileIdentityService.java] [here|https://github.com/petalslink/petals-se-flowable/blob/petals-se-flowable/src/main/java/org/ow2/petals/flowable/identity/file/FileIdentityService.java] (the file-based entity service).
h1. Configuring the component
* *JBI parameters* that have not to be changed otherwise the component will not work,
* *CDK parameters* that are parameters driving the processing of the CDK layer,
* *CDK parameters* that are parameters driving the processing of the CDK layer,
* and *Activiti *Flowable engine parameters* that are relative to the Activiti Flowable engine.
{code:lang=xml}
<jbi:jbi xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5"
xmlns:jbi="http://java.sun.com/xml/ns/jbi" version="1.0"
xmlns:petals-se-activitibpmn="http://petals.ow2.org/components/petals-se-activitibpmn/1.0"> xmlns:petals-se-flowable="http://petals.ow2.org/components/flowable/1.0">
<jbi:component type="service-engine">
<jbi:identification>
<jbi:name>petals-se-activitibpmn</jbi:name> <jbi:name>petals-se-flowable</jbi:name>
<jbi:description>Petals SE Activiti</jbi:description> Flowable</jbi:description>
</jbi:identification>
<jbi:component-class-name>org.ow2.petals.activitibpmn.ActivitiSE</jbi:component-class-name> <jbi:component-class-name>org.ow2.petals.flowable.FlowableSE</jbi:component-class-name>
<jbi:component-class-path>
<jbi:path-element />
</jbi:component-class-path>
<jbi:path-element />
</jbi:component-class-path>
<jbi:bootstrap-class-name>org.ow2.petals.activitibpmn.ActivitiSEBootstrap</jbi:bootstrap-class-name> <jbi:bootstrap-class-name>org.ow2.petals.flowable.FlowableSEBootstrap</jbi:bootstrap-class-name>
<jbi:bootstrap-class-path>
<jbi:path-element />
<jbi:path-element />
<petalsCDK:time-beetween-async-cleaner-runs />
<petalsCDK:properties-file />
<petalsCDK:properties-file />
<petalsCDK:jbi-listener-class-name>org.ow2.petals.activitibpmn.incoming.ActivitiJBIListener</petalsCDK:jbi-listener-class-name> <petalsCDK:jbi-listener-class-name>org.ow2.petals.flowable.incoming.FlowableJBIListener</petalsCDK:jbi-listener-class-name>
<!-- Component specific configuration -->
<petals-se-activitibpmn:jdbc_driver>org.h2.Driver</petals-se-activitibpmn:jdbc_driver> <petals-se-flowable:jdbc_driver>org.h2.Driver</petals-se-flowable:jdbc_driver>
<petals-se-activitibpmn:jdbc_url <petals-se-flowable:jdbc_url />
<petals-se-activitibpmn:jdbc_username>sa</petals-se-activitibpmn:jdbc_username> <petals-se-flowable:jdbc_username>sa</petals-se-flowable:jdbc_username>
<petals-se-activitibpmn:jdbc_password></petals-se-activitibpmn:jdbc_password> <petals-se-flowable:jdbc_password></petals-se-flowable:jdbc_password>
<petals-se-activitibpmn:jdbc_max_active_connections <petals-se-flowable:jdbc_max_active_connections />
<petals-se-activitibpmn:jdbc_max_idle_connections <petals-se-flowable:jdbc_max_idle_connections />
<petals-se-activitibpmn:jdbc_max_checkout_time <petals-se-flowable:jdbc_max_checkout_time />
<petals-se-activitibpmn:jdbc_max_wait_time <petals-se-flowable:jdbc_max_wait_time />
<petals-se-activitibpmn:database_type <petals-se-flowable:database_type />
<petals-se-activitibpmn:database_schema_update <petals-se-flowable:database_schema_update />
<petals-se-activitibpmn:engine-enable-job-executor <petals-se-flowable:engine-enable-job-executor />
<petals-se-activitibpmn:engine-job-executor-core-pool-size <petals-se-flowable:engine-job-executor-core-pool-size />
<petals-se-activitibpmn:engine-job-executor-max-pool-size <petals-se-flowable:engine-job-executor-max-pool-size />
<petals-se-activitibpmn:engine-job-executor-keep-alive-time <petals-se-flowable:engine-job-executor-keep-alive-time />
<petals-se-activitibpmn:engine-job-executor-queue-size <petals-se-flowable:engine-job-executor-queue-size />
<petals-se-activitibpmn:engine-job-executor-max-timer-jobs-per-acquisition <petals-se-flowable:engine-job-executor-max-timer-jobs-per-acquisition />
<petals-se-activitibpmn:engine-job-executor-max-async-jobs-due-per-acquisition <petals-se-flowable:engine-job-executor-max-async-jobs-due-per-acquisition />
<petals-se-activitibpmn:engine-job-executor-async-job-acquire-wait-time <petals-se-flowable:engine-job-executor-async-job-acquire-wait-time />
<petals-se-activitibpmn:engine-job-executor-timer-job-acquire-wait-time <petals-se-flowable:engine-job-executor-timer-job-acquire-wait-time />
<petals-se-activitibpmn:engine-job-executor-timer-lock-time <petals-se-flowable:engine-job-executor-timer-lock-time />
<petals-se-activitibpmn:engine-job-executor-async-job-lock-time <petals-se-flowable:engine-job-executor-async-job-lock-time />
<petals-se-activitibpmn:engine-enable-bpmn-validation <petals-se-flowable:engine-enable-bpmn-validation />
<petals-se-activitibpmn:engine-identity-service-class-name <petals-se-flowable:engine-identity-service-class-name />
<petals-se-activitibpmn:engine-identity-service-config-file <petals-se-flowable:engine-identity-service-config-file />
</jbi:component>
h2. Component specific parameters
These parameters drive features proposed by the component and configure the Activiti Flowable engine "Activiti 5.18.0-PETALS-0" embedded in the SE:
* activation of the mode 'integration',
* Activiti Flowable engine configuration:
** the database parameters: your are responsible to provide this database according to your needs. And especially, you must assume that the database is highly available to have a SE Activiti Flowable highly available,
** asynchronous job executor activation and configuration,
** BPMN validation,
** BPMN validation,
|| {color:#333333}Parameter{color} || {color:#333333}Description{color} || {color:#333333}Default{color} || {color:#333333}Required{color} || Scope ||
| integration-mode-enable | Enable the mode 'Integration' | {center}true{center} | {center}No{center} | {center}Installation{center} |
| integration-mode-enable | Enable the mode 'Integration' | {center}true{center} | {center}No{center} | {center}Installation{center} |
| jdbc_url | URL of the database. The default database is an in-memory database | {center}jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000{center} {center}jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000{center} | {center}Yes{center} | {center}Installation{center} |
| jdbc_driver | JDBC driver. Except for the default JDBC driver, it *must* be provided as shared-library. | {center}org.h2.Driver{center} | {center}Yes{center} | {center}Installation{center} |
| jdbc_username | Username used for the database connection. | {center}sa{center} | {center}Yes{center} | {center}Installation{center} |
| jdbc_username | Username used for the database connection. | {center}sa{center} | {center}Yes{center} | {center}Installation{center} |
| jdbc_max_checkout_time | The amount of time in milliseconds a connection can be 'checked out' from the connection pool before it is forcefully returned. | {center}20000 (20 seconds){center} | {center}No{center} | {center}Installation{center} |
| jdbc_max_wait_time | This is a low level setting that gives the pool a chance to print a log status and re-attempt the acquisition of a connection in the case that it’s taking unusually long (to avoid failing silently forever if the pool is misconfigured). | {center}20000 (20 seconds){center} | {center}No{center} | {center}Installation{center} |
| jdbc_max_wait_time | This is a low level setting that gives the pool a chance to print a log status and re-attempt the acquisition of a connection in the case that it’s taking unusually long (to avoid failing silently forever if the pool is misconfigured). | {center}20000 (20 seconds){center} | {center}No{center} | {center}Installation{center} |
| database_type | The database type: it's normally not necessary to specify this property it is automatically analyzed from the database connection meta data. Should only be specified in case automatic detection fails on Activiti Flowable engine side. Possible values: {{h2}}, {{mysql}}, {{oracle}}, {{postgres}}, {{mssql}}, {{db2}}. | {center}-{center} | {center}No{center} | {center}Installation{center} |
| database_schema_update | The database schema update: allows to set the strategy to handle the database schema on process engine boot and shutdown:
* false: Checks the version of the DB schema against the library when the process engine is being created and throws an exception if the versions don't match.
* true: Upon building the process engine, a check is performed and an update of the schema is performed if it is necessary. If the schema doesn't exist, it is created.
* create-drop: Creates the schema when the process engine is being created and drops the schema when the process engine is being closed. | {center}true{center} | {center}No{center} | {center}Installation{center} |
* false: Checks the version of the DB schema against the library when the process engine is being created and throws an exception if the versions don't match.
* true: Upon building the process engine, a check is performed and an update of the schema is performed if it is necessary. If the schema doesn't exist, it is created.
* create-drop: Creates the schema when the process engine is being created and drops the schema when the process engine is being closed. | {center}true{center} | {center}No{center} | {center}Installation{center} |
| engine-enable-job-executor | Enable or disable the Activiti Flowable job executor. See [Enabling/disabling the Activiti Flowable job executor|#job_executor] | {center}true{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-core-pool-size | The minimal number of threads that are kept alive in the thread pool for job execution of the Activiti Flowable engine job executor. | {center}2{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-max-pool-size | The maximum number of threads that are kept alive in the thread pool for job execution of the Activiti Flowable engine job executor. | {center}10{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-keep-alive-time | The time, in milliseconds, a thread used for job execution must be kept alive before it is destroyed. | {center}5000{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-queue-size | The size of the queue on which jobs to be executed are placed. | {center}100{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-queue-size | The size of the queue on which jobs to be executed are placed. | {center}100{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-timer-lock-time | The time, in milliseconds, that a timer job is locked before being retried again. | {center}300000{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-async-job-lock-time | The time in milliseconds that an asynchronous job is locked before being retried again. | {center}300000{center} | {center}No{center} | {center}Installation{center} |
| engine-job-executor-async-job-lock-time | The time in milliseconds that an asynchronous job is locked before being retried again. | {center}300000{center} | {center}No{center} | {center}Installation{center} |
| engine-enable-bpmn-validation | Enable or disable the BPMN validation of processes to deploy into the Activiti Flowable engine | {center}true{center} | {center}No{center} | {center}Installation{center} |
| engine-identity-service-class-name | Class name of the entity service to use. | {center}{{org.ow2.petals.activitibpmn.identity.file.FileIdentityService}}{center} {center}{{org.ow2.petals.flowable.identity.file.FileIdentityService}}{center} | {center}No{center} | {center}Installation{center} |
| engine-identity-service-config-file | Configuration file of the entity service used. | {center}The default configuration of the entity service is service dependent. See documentation of the entity service{center} | {center}No{center} | {center}Installation{center} |
{anchor:job_executor}
{anchor:job_executor}
h3. Enabling/disabling the Activiti Flowable job executor
Activiti Flowable requires a job executor to manage a couple of threads to fire timers, to invoke service tasks, other asynchronous tasks. At least one job executor is required.
When deploying several Petals SE Activiti Flowable running with the same database, you can disable the job executor on some Petals SE Activiti. Flowable. Or even, you can specialized a Petals SE Activiti Flowable to process all asynchronous tasks enabling the job executor on only one Petals SE Activiti. Flowable.
h1. Business monitoring
h1. Logging
The traces of the BPMN 2.0 engine "Activiti" "Flowable" are activated through the logging configuration file of Petals ESB. The root logger for Activiti Flowable is {{org.activiti}}: {{org.flowable}}:
{code}
...
...
org.activiti.level=INFO org.flowable.level=INFO
org.activiti.engine.impl.level=FINE org.flowable.engine.impl.level=FINE
...
{code}
{code}
Moreover the common metrics, some dedicated alerts can be sent by the component:
|| Defect || JMX Notification ||
|| Defect || JMX Notification ||
| No more thread is available for the asynchronous job executor | * type: {{org.ow2.petals.se.activiti.engine.async.executor.thread.pool.exhausted}} {{org.ow2.petals.se.flowable.engine.async.executor.thread.pool.exhausted}}
* no user data |
| No more connection is available in the database pool | * type: {{org.ow2.petals.se.activiti.engine.database.connection.pool.exhausted}} {{org.ow2.petals.se.flowable.engine.database.connection.pool.exhausted}}
* no user data |
h1. Unit testing
The unit testing can occur at several levels in your Activiti Flowable service unit:
* to check the annotation compliance of the WSDL with the attendees of the component,
* to unit test your XSL generating outputs,
* to unit test your XSL generating outputs,
* to verify easily the XSL used to generate output replies.
This dedicated framework is provided by the Maven artifact {{org.ow2.petals:petals-se-activiti-junit}}: {{org.ow2.petals:petals-se-flowable-junit}}:
{code:xml}
<project>
<project>
<dependency>
<groupId>org.ow2.petals</groupId>
<groupId>org.ow2.petals</groupId>
<artifactId>petals-se-activiti-junit</artifactId> <artifactId>petals-se-flowable-junit</artifactId>
<version>1.0.0</version>
<scope>test</scope>
<scope>test</scope>
{code}
{warning}The version 1.0.0+ of the framework is compliant with the Petals SE Activiti 1.0.3+.{warning} Flowable 1.0.0+.{warning}
h2. Checking the compliance of the WSDL
The unit test framework contains an assertion '{{assertWsdlCompliance}}' to verify easily the compliance of your WSDL with the attendees of the mode 'service':
{code:lang=java}
{code:lang=java}
import static org.ow2.petals.activitibpmn.junit.Assert.assertWsdlCompliance; org.ow2.petals.flowable.junit.Assert.assertWsdlCompliance;
import javax.xml.namespace.QName;
import org.junit.Test;
import org.junit.Test;
@Test
public void validate() throws Exception {
public void validate() throws Exception {
assertWsdlCompliance(new QName[] { new QName("http://petals.ow2.org/samples/se-bpmn/vacationService", QName("http://petals.ow2.org/samples/se-flowable/vacationService", "new"),
new QName("http://petals.ow2.org/samples/se-bpmn/vacationService", QName("http://petals.ow2.org/samples/se-flowable/vacationService", "validate"),
new QName("http://petals.ow2.org/samples/se-bpmn/vacationService", QName("http://petals.ow2.org/samples/se-flowable/vacationService", "update") });
}
The unit test framework contains an assertion '{{assertXslTransformation}}' to verify easily the result of your XSL transformations:
{code:lang=java}
{code:lang=java}
import static org.ow2.petals.activitibpmn.junit.Assert.assertXslTransformation; org.ow2.petals.flowable.junit.Assert.assertXslTransformation;
import ...
import org.junit.Test;
import org.junit.Test;
h2. Unit-testing your process definition
Activiti Flowable provides a JUnit framework to write unit tests about business processes. You can find several articles on this subject on Internet, for example [here|http://docs.alfresco.com/activiti/topics/apiUnitTesting.html].
We don't discuss how to use the Activiti Flowable JUnit framework but how to integrate it into a service unit project.
First, you must embedd an Activiti Flowable engine for your test, adding an dependency on it with scope {{test}} into your POM file. Don't forget to add also the JDBC driver, H2 for example:
{code:xml}
<project>
<project>
...
<dependency>
<dependency>
<groupId>org.ow2.petals.activiti</groupId> <groupId>org.flowable</groupId>
<artifactId>activiti-engine</artifactId> <artifactId>flowable-engine</artifactId>
<version>5.22.0-PETALS-0</version> <version>5.23</version>
<scope>test</scope>
</dependency>
</dependency>
</project>
{code}
{code}
{tip}Caution to use the same version of the Activiti Flowable engine as the one embedded into the Petals SE Activiti{tip} Flowable{tip}
Next, your database must be linked to the Activiti Flowable engine through a Spring configuration located into the file {{src/test/resources/activiti.cfg.xml}} {{src/test/resources/flowable.cfg.xml}} containing something like:
{code:xml}
<beans xmlns="http://www.springframework.org/schema/beans"
<beans xmlns="http://www.springframework.org/schema/beans"
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcUsername" value="sa" />
{code}
So, with this, you will be able to test the deployment of your process definition and check process instance creations using the Activiti Flowable JUnit framework:
{code:java}
public class ProcessDeploymentTest {
@Rule
public class ProcessDeploymentTest {
@Rule
public final ActivitiRule activitiRule FlowableRule flowableRule = new ActivitiRule(); FlowableRule();
@Test
@Deployment(resources = {"jbi/vacationRequest.bpmn20.xml"})
public void theProcessIsDeployableAndInstanciable() {
final ProcessDefinition processDefinition = this.activitiRule.getRepositoryService() this.flowableRule.getRepositoryService()
.createProcessDefinitionQuery().processDefinitionKey("vacationRequest").singleResult();
assertNotNull(processDefinition);
assertNotNull(processDefinition);
variables.put("startDate", new Date());
variables.put("vacationMotivation", "Vacations");
variables.put("vacationMotivation", "Vacations");
final ProcessInstance processInstance = this.activitiRule.getRuntimeService().startProcessInstanceByKey("vacationRequest", this.flowableRule.getRuntimeService().startProcessInstanceByKey("vacationRequest", variables);
assertNotNull(processInstance);
}
}
{code:xml}
<bean id="archiveEndpoint" class="javax.xml.namespace.QName">
<bean id="archiveEndpoint" class="javax.xml.namespace.QName">
<constructor-arg index="0" value="http://petals.ow2.org/samples/se-bpmn/archiveService" value="http://petals.ow2.org/samples/se-flowable/archiveService" />
<constructor-arg index="1" value="autogenerate" />
</bean>
<bean id="notifyEndpoint" class="javax.xml.namespace.QName">
</bean>
<bean id="notifyEndpoint" class="javax.xml.namespace.QName">
<constructor-arg index="0" value="http://petals.ow2.org/samples/se-bpmn/notifyVacationService" value="http://petals.ow2.org/samples/se-flowable/notifyVacationService" />
<constructor-arg index="1" value="autogenerate" />
</bean>
</bean>
<id>startup-mock-archive</id>
<configuration>
<configuration>
<projectFile>${basedir}/src/test/soapui/su-activiti-vacationService-provide-soapui-project.xml</projectFile> <projectFile>${basedir}/src/test/soapui/su-flowable-vacationService-provide-soapui-project.xml</projectFile>
<mockService>archiveSoapBinding MockService</mockService>
<noBlock>true</noBlock>
<noBlock>true</noBlock>
<id>startup-mock-notify</id>
<configuration>
<configuration>
<projectFile>${basedir}/src/test/soapui/su-activiti-vacationService-provide-soapui-project.xml</projectFile> <projectFile>${basedir}/src/test/soapui/su-flowable-vacationService-provide-soapui-project.xml</projectFile>
<mockService>notifyVacationBinding MockService</mockService>
<noBlock>true</noBlock>
<noBlock>true</noBlock>
{code}
where SoapUI project files contains mock service definitions.
where SoapUI project files contains mock service definitions.
h1. Annex: Sample WSDL
h2. Abstract part:
{code:lang=xml}
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns="http://petals.ow2.org/se/bpmn2/sample/order"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://petals.ow2.org/se/bpmn2/sample/order">
<!-- Type definitions for input and output parameters for service -->
<wsdl:types>
<xs:schema targetNamespace="http://petals.ow2.org/se/bpmn2/sample/order">
<xs:complexType name="ItemType">
<xs:sequence>
<xs:element name="reference" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="quantity" type="xs:int" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:element name="newOrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="customerName" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="address" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="items">
<xs:complexType>
<xs:sequence>
<xs:element name="item" type="tns:ItemType"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="newOrderResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="orderId" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="validOrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="orderId" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="validationStepId" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="isValidated" type="xs:boolean" minOccurs="1" maxOccurs="1" />
<xs:element name="creditCardNumber" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="validOrderResponse" type="xs:string" />
<xs:element name="searchOrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="orderId" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="isInProgress" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="responsibleUser" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="responsibleGroup" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="searchOrderResponse" type="xs:string" />
</xs:schema>
<xs:element name="orderUnknownFault">
<xs:complexType>
<xs:sequence>
<xs:element name="orderId" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="orderAlreadyValidated">
<xs:complexType>
<xs:sequence>
<xs:element name="orderId" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</wsdl:types>
<!-- Message definitions for input and output -->
<wsdl:message name="newOrderRequest">
<wsdl:part name="newOrderRequest" element="tns:newOrderRequest" />
</wsdl:message>
<wsdl:message name="newOrderResponse">
<wsdl:part name="newOrderResponse" element="tns:newOrderResponse" />
</wsdl:message>
<wsdl:message name="validOrderRequest">
<wsdl:part name="validOrderRequest" element="tns:validOrderRequest" />
</wsdl:message>
<wsdl:message name="validOrderResponse">
<wsdl:part name="validOrderResponse" element="tns:validOrderResponse" />
</wsdl:message>
<wsdl:message name="searchOrderRequest">
<wsdl:part name="searchOrderRequest" element="tns:validOrderRequest" />
</wsdl:message>
<wsdl:message name="searchOrderResponse">
<wsdl:part name="searchOrderResponse" element="tns:searchOrderResponse" />
</wsdl:message>
<wsdl:message name="orderUnknown">
<wsdl:part name="orderUnknown" element="tns:orderUnknownFault" />
</wsdl:message>
<wsdl:message name="orderAlreadyValidated">
<wsdl:part name="orderAlreadyValidated" element="tns:orderAlreadyValidated" />
</wsdl:message>
<!-- Port (interface) definitions -->
<wsdl:portType name="Order">
<wsdl:operation name="newOrder">
<wsdl:input message="tns:newOrderRequest" />
<wsdl:output message="tns:newOrderResponse" />
</wsdl:operation>
<wsdl:operation name="validOrder">
<wsdl:input message="tns:validOrderRequest" />
<wsdl:output message="tns:validOrderResponse" />
<wsdl:fault message="tns:orderUnknown" name="orderUnknown"/>
<wsdl:fault message="tns:orderAlreadyValidated" name="orderAlreadyValidated"/>
</wsdl:operation>
<wsdl:operation name="searchOrder">
<wsdl:input message="tns:searchOrderRequest" />
<wsdl:output message="tns:searchOrderResponse" />
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
{code}
h2. Implementation part
{code:lang=xml}
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns="http://petals.ow2.org/se/bpmn2/sample/order"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:bpmn="http://petals.ow2.org/se/bpmn2/1.0" targetNamespace="http://petals.ow2.org/se/bpmn2/sample/order">
<wsdl:import location="OrderAbstract.wsdl"
namespace="http://petals.ow2.org/se/bpmn2/sample/order" />
<!-- Port bindings to SE Activiti -->
<wsdl:binding name="OrderBinding" type="tns:Order">
<wsdl:operation name="newOrder">
<bpmn:operation processDefinitionId="order" action="startEvent" start-event-message-name="newOrder"/>
<bpmn:userId>/*[local-name()='newOrderRequest']/*[local-name()='userName']</bpmn:userId>
<bpmn:variable name="customerName">
/*[local-name()='newOrderRequest']/*[local-name()='customerName']
</bpmn:variable>
<bpmn:variable name="address">
/*[local-name()='newOrderRequest']/*[local-name()='address']
</bpmn:variable>
<bpmn:output>newOrderOutput.xsl</bpmn:output>
<wsdl:input />
<wsdl:output />
</wsdl:operation>
<wsdl:operation name="validOrder">
<bpmn:operation processDefinitionId="order" action="userTask" user-task-id="validOrder"/>
<bpmn:processId>/*[local-name()='validOrderRequest']/*[local-name()='orderId']</bpmn:processId>
<bpmn:userId>/*[local-name()='validOrderRequest']/*[local-name()='userName']</bpmn:userId>
<bpmn:variable name="validationApproved">
/*[local-name()='validOrderRequest']/*[local-name()='isValidated']
</bpmn:variable>
<bpmn:variable name="creditCardNumber">
/*[local-name()='validOrderRequest']/*[local-name()='creditCardNumber']
</bpmn:variable>
<bpmn:output>validOrderOutput.xsl</bpmn:output>
<wsdl:input />
<wsdl:output />
<wsdl:fault name="orderUnknown">
<bpmn:fault name="ProcessInstanceNotFoundException">orderUnknown.xsl</bpmn:fault>
<soap:fault name="orderUnknown" use="literal" />
</wsdl:fault>
<wsdl:fault name="orderAlreadyValidated">
<bpmn:fault name="TaskCompletedException">orderAlreadyValidated.xsl</bpmn:fault>
<soap:fault name="orderAlreadyValidated" use="literal" />
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="searchOrder">
<bpmn:operation action="retrieveProcInst" />
<bpmn:input-parameter name="processInstanceId" value="/searchOrderRequest/orderId" />
<bpmn:input-parameter name="isActive" value="/searchOrderRequest/isInProgress" />
<bpmn:input-parameter name="responsibleUser" value="/searchOrderRequest/responsibleUser" />
<bpmn:input-parameter name="responsibleGroup" value="/searchOrderRequest/responsibleGroup" />
<bpmn:output>searchOrderOutput.xsl</bpmn:output>
<wsdl:input />
<wsdl:output />
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>
{code}