Activiti BPMN notions

BPM (Business Process Management)

  • Lifecycle stages:
    1. Design - by analyst and managers -> BPMN graph
    2. Model - developers and sysadmins -> add logic
    3. Execute - on a machine - get results
    4. Monitor - check the data from the machine
    5. Optimize - improve and go back to model
graph LR;
A(start);
B[order pizza];
C[bake pizza];
D[eat pizza];
E(finish)
A --> B;
B --> C;
C --> D;
D --> E;

Alfresco Activiti

Open source workflow in Java

  • engine
  • database
  • REST API
  • Spring framework (JPA, CDI, LDAP, JMX)

Process overview

All this can be called by REST

graph LR;
A[Model xml];
B[Process definition structure];
C[Process instance];
A --> |Deploy in Activiti| B
B --> |Triggers and user actionsi| C

Designing a model (xml)

Elements

  • Start events
  • Boundary events
  • Intermediate events
  • End events
  • Subprocess (normal line box)
  • Event subprocess (not continuous line box)
  • Call activiti (bold line box): may create new instance -> external call
  • Tasks (work units)
  • Gateways
  • Sequence flow

Events

  • Blank: API call
  • Timer (clock)
  • Message (postcardl) : local
  • *Signal (triangle):global
  • Cancel (cross)
  • Error (lightning): in error no case, not an exception, the right idea is to catch the exception and launch this event

Tasks

  • User task (you can specif the user role)
  • Service task (my Java code, call SOAP)
  • Script task (launch a script, js or groovy, internal logic)
  • There are also BusinessRuleTask, ReceiveTask, ManualTask, MailTask, CamelTask, MuleTask

Gateways

  • Exclusive (EX-OR, only one line on split, only waits for one)
  • Parallel (AND, several lines on split, waits for everyone to finish)
  • Inclusive (EX-AND, wait to continue)
  • Event-based - generates new process instance

Sequence flow

  • Normal
  • Default (crossed arrow)
  • Message flow (discontinuous)
  • Pools and lanes (e.g. vendor, client) -> to optimize

Best practices

  • Unique names
  • Avoid crossing flows
  • Modularize models
  • Naming conventions (verb + object)
  • Use comments
  • Avoid deadlocks and multimerges
  • Split flow with gateways
  • Avoid split and join at the same point
  • Avoid splitting tasks after events: get the result first
  • Void ecursive subprocess (beware infinite loops)
  • Consistent usage of Start and En events (only one start point)

❗ Note: an actor may have several roles (e.g. amazon has a picker and a packager in its storage place, but the same person can pick and package). Hence you can have a pool with 2 lanes.

Comunication with Activiti

  1. Go to activiti backend and extend (bad!)
  2. Use REST (good)

REST

  • Model
  • Deployments
  • Process definition
  • Process instances
  • Executions
  • Tasks
  • Froms
  • History
  • DB Tables
  • Jobs
  • Users and groups
    ⚠️ Add \service as a prefix to every REST call on the Activiti guide, and use camel case names for ids, so it’s directly mapped to Java.

The Activiti database

Tables:

  • ACT_AVT: events
  • ACT_GE_XXX: binaries, don’t touch
  • ACT_HI_XXX: history (read only, or that’s supposed. Don’t touch!!)
  • ACT_ID_XXX: users and groups
  • ACT_RU_XXX: runtime
    • IDENTITY_LINK: task X is assigned by user Y
    • EVENT_SUBSCR: event subscriber, listeners: task X will be done in 60 minutes
    • EXECUTION: be carefull with joins.
    • JOB: planned tasks (QuartzScheduler will execute a task) -> Quartz’s queue
    • TASK: they are timed
  • ACT_PROCDEF_INFO: the xml model parsed is stored here

⚠️ Don’t modify the schema! Upgrades can be horrible.
* Set associations in a different database.
* Be careful to be consistent.
* Activiti should be the master (don’t overwrite it with the associated DB data)

UIs

  • Activiti explorer
    It’s heavy on PROD. You only deploy this on demand. You usually connect to the database.

    • UI elements

      • Query
      • DB
      • Deployments: be carefull as it does “waterfall deletions”: delete a deployemnt and you’ll phisically destroy everything
    • Process

      • Instances (check active instances)
      • Process definitions (models) -> tenant: similar to environment, but you can only use it with REST
      • Model workspace : you can edit and deploy from here

    ⚠️ Tenants can only be modified via REST API by adding an input form and changing the value for “script”
    ⚠️ Use this app only for queries and very carefully, it’s easy to end in accidental cleansing fire.
    ⚠️ Activiti usually doens’t send back an answer after put (maybe 204). You should do a get after that.
    ⚠️ Error code 409 notifies conlicts (e.g. problems with concurrency and exclusion -> someone else already did that, so you can remove it from your cache)

  • Eclipse

  • Camunda

    • Big models

Properties

  • engine properties
    data
    1
    2
    3
    4
    # demo data
    cretate.demo.users = true
    cretate.demo.definitions = true
    cretate.demo.models report = true
  • db.properties: don’t forget about the connector
    1
    2
    3
    4
    5
    jdbc.type = mysql
    jdbc.driver = com.mysql.jdbc.Driver
    jdbc.url = jdbc:mysql://localhost:3306/activiti?autoReconnect=true
    username = root
    password =
  • log4j.properties
    1
    2
    3
    4
    5
    6
    log4j.rootLogger=INFO, CA

    # ConsoleAppender
    log4j.appender.CA=org.apache.log4j.ConsoleAppender
    log4j.appender.CA.layout=org.apache.log4j.PatternLayout
    log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

Methodology

3 options:

  • set up your_code inside Activiti -> set your code in the lib activiti in the war, mainly for REST

    • Fast: activiti provides
    • You set up your models in the jar or a external zip
    • Easier versioning
  • set up Activiti inside your_code -> create your own endpoints (horrible idea)

    • Modifier Activiti itself, and overwrites it (the horror!!)
    • you set it up “the hardcore way”, you are overwriting it
  • Use Activiti as a library -> reuse DB instances, your own models

    • Set is as a dependency
    • You extend it
  • Install on eclipse

    • Get 2 wars (activiti-explorer and activit-rest)
    • Copy them in a Tomcat (webapps folder)
    • Deploy tomcat so it creates the projects
    • Compile your project on eclipse (Activiti project, clean install)
    • Copy:
      • lib: copy jars in both projects
      • classes: copy properties in both projects
  • Implementation of the Java code

1
2
3
4
5
6
public class ClientRest implements JavaDelegate or extends BaseEntityEventListener{
...
public void execute(){
...
}
}