== Getting Started === What is Flowable? Flowable is a light-weight business process engine written in Java. The Flowable process engine allows you to deploy BPMN 2.0 process definitions (an industry XML standard for defining processes), creating process instances of those process definitions, running queries, accessing active or historical process instances and related data, plus much more. This section will gradually introduce various concepts and APIs to do that through examples that you can follow on your own development machine. Flowable is extremely flexible when it comes to adding it to your application/services/architecture. You can _embed_ the engine in your application or service by including the Flowable library, which is available as a JAR. Since it's a JAR, you can add it easily to any Java environment: Java SE; servlet containers, such as Tomcat or Jetty, Spring; Java EE servers, such as JBoss or WebSphere, and so on. Alternatively, you can use the Flowable REST API to communicate over HTTP. There are also several Flowable Applications (Flowable Modeler, Flowable Admin, Flowable IDM and Flowable Task) that offer out-of-the-box example UIs for working with processes and tasks. Common to all the ways of setting up Flowable is the core engine, which can be seen as a collection of services that expose APIs to manage and execute business processes. The various tutorials below start by introducing how to set up and use this core engine. The sections afterwards build upon the knowledge acquired in the previous sections. * The <> shows how to run Flowable in the simplest way possible: a regular Java main using only Java SE. Many core concepts and APIs will be explained here. * The <> shows how to run and use the same API through REST. * The <>, will guide you through the basics of using the out-of-the-box example Flowable user interfaces. === Flowable and Activiti Flowable is a fork of Activiti (registered trademark of Alfresco). In all the following sections you’ll notice that the package names, configuration files, and so on, use _flowable_. [[getting.started.command.line]] === Building a command-line application ==== Creating a process engine In this first tutorial we're going to build a simple example that shows how to create a Flowable process engine, introduces some core concepts and shows how to work with the API. The screenshots show Eclipse, but any IDE works. We'll use Maven to fetch the Flowable dependencies and manage the build, but likewise, any alternative also works (Gradle, Ivy, and so on). The example we'll build is a simple _holiday request_ process: * the _employee_ asks for a number of holidays * the _manager_ either approves or rejects the request * we'll mimic registering the request in some external system and sending out an email to the employee with the result First, we create a new Maven project through _File -> New -> Other -> Maven Project_ image::images/getting.started.new.maven.png[align="center"] In the next screen, we check '_create a simple project (skip archetype selection)_' image::images/getting.started.new.maven2.png[align="center"] And fill in some _'Group Id'_ and _'Artifact id'_: image::images/getting.started.new.maven3.png[align="center"] We now have an empty Maven project, to which we'll add two dependencies: * The Flowable process engine, which will allow us to create a ProcessEngine object and access the Flowable APIs. * An in-memory database, H2 in this case, as the Flowable engine needs a database to store execution and historical data while running process instances. Note that the H2 dependency includes both the database _and_ the driver. If you use another database (for example, PostgresQL, MySQL, and so on), you'll need to add the specific database driver dependency. Add the following to your _pom.xml_ file: [source,xml,linenums] ---- org.flowable flowable-engine 6.3.0 com.h2database h2 1.3.176 ---- If the dependent JARs are not automatically retrieved for some reason, you can right-click the project and select '_Maven -> Update Project'_ to force a manual refresh (but this should not be needed, normally). In the project, under '_Maven Dependencies_', you should now see the _flowable-engine_ and various other (transitive) dependencies. Create a new Java class and add a regular Java main method: [source,java,linenums] ---- package org.flowable; public class HolidayRequest { public static void main(String[] args) { } } ---- The first thing we need to do is to instantiate a *ProcessEngine* instance. This is a thread-safe object that you typically have to instantiate only once in an application. A _ProcessEngine_ is created from a *ProcessEngineConfiguration* instance, which allows you to configure and tweak the settings for the process engine. Often, the _ProcessEngineConfiguration_ is created using a configuration XML file, but (as we do here) you can also create it programmatically. The minimum configuration a _ProcessEngineConfiguration_ needs is a JDBC connection to a database: [source,java,linenums] ---- package org.flowable; import org.flowable.engine.ProcessEngine; import org.flowable.engine.ProcessEngineConfiguration; import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration; public class HolidayRequest { public static void main(String[] args) { ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1") .setJdbcUsername("sa") .setJdbcPassword("") .setJdbcDriver("org.h2.Driver") .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); ProcessEngine processEngine = cfg.buildProcessEngine(); } } ---- In the code above, on line 10, a _standalone_ configuration object is created. The _'standalone'_ here refers to the fact that the engine is created and used completely by itself (and not, for example, in a Spring environment, where you'd use the _SpringProcessEngineConfiguration_ class instead). On lines 11 to 14, the JDBC connection parameters to an in-memory H2 database instance are passed. Important: note that such a database does not survive a JVM restart. If you want your data to be persistent, you'll need to switch to a persistent database and switch the connection parameters accordingly. On line 15 we're setting a flag to _true_ to make sure that the database schema is created if it doesn't already exist in the database pointed to by the JDBC parameters. Alternatively, Flowable ships with a set of SQL files that can be used to create the database schema with all the tables manually. The *ProcessEngine* object is then created using this configuration (line 17). You can now run this. The easiest way in Eclipse is to right-click on the class file and select _Run As -> Java Application_: image::images/getting.started.run.main.png[align="center"] The application runs without problems, however, no useful information is shown in the console except a message stating that the logging has not been configured properly: image::images/getting.started.console.logging.png[align="center"] Flowable uses link:$$http://www.slf4j.org/$$[SLF4J] as its logging framework internally. For this example, we'll use the log4j logger over SLF4j, so add the following dependencies to the pom.xml file: [source,xml,linenums] ---- org.slf4j slf4j-api 1.7.21 org.slf4j slf4j-log4j12 1.7.21 ---- Log4j needs a properties file for configuration. Add a _log4j.properties_ file to the _src/main/resources_ folder with the following content: ---- log4j.rootLogger=DEBUG, CA 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 ---- Rerun the application. You should now see informative logging about the engine booting up and the database schema being created in the database: image::images/getting.started.console.logging2.png[align="center"] We've now got a process engine booted up and ready to go. Time to feed it a process! ==== Deploying a process definition The process we'll build is a very simple holiday request process. The Flowable engine expects processes to be defined in the BPMN 2.0 format, which is an XML standard that is widely accepted in the industry. In Flowable terminology, we speak about this as a *process definition*. From a _process definition_, many *process instances* can be started. Think of the _process definition_ as the blueprint for many executions of the process. In this particular case, the _process definition_ defines the different steps involved in requesting holidays, while one _process instance_ matches the request for a holiday by one particular employee. BPMN 2.0 is stored as XML, but it has a visualization part too: it defines in a standard way how each different step type (a human task, an automatic service call, and so on) is represented and how to connect these different steps to each other. Through this, the BPMN 2.0 standard allows technical and business people to communicate about business processes in a way that both parties understand. The process definition we'll use is the following: image::images/getting.started.bpmn.process.png[align="center"] The process should be quite self-explanatory, but for clarity's sake let's describe the different bits: * We assume the process is started by providing some information, such as the employee name, the amount of holiday requested and a description. Of course, this could be modeled as a separate first step in the process. However, by having it as 'input data' for the process, a process instance is only actually created when a real request has been made. In the alternative case, a user could change his mind and cancel before submitting, yet the process instance would now be there. In some scenarios this could be valuable information (for example, how many times is a request started, but not finished), depending on the business goal. * The circle on the left is called a *start event*. It's the starting point of a process instance. * The first rectangle is a *user task*. This is a step in the process that a human user has to perform. In this case, the manager needs to approve or reject the request. * Depending on what the manager decides, the *exclusive gateway* (the diamond shape with the cross) will route the process instance to either the approval or the rejection path. * If approved, we have to register the request in some external system, which is followed by a user task again for the original employee that notifies them of the decision. This could, of course, be replaced by an email. * If rejected, an email is sent to the employee informing them of this. Typically, such a _process definition_ is modeled with a visual modeling tool, such as the Flowable Designer (Eclipse) or the Flowable Modeler (web application). Here, however, we're going to write the XML directly to familiarize ourselves with BPMN 2.0 and its concepts. The BPMN 2.0 XML corresponding to the diagram above is shown below. Note that this is only the 'process part'. If you'd used a graphical modeling tool, the underlying XML file also contains the 'visualization' part that describes the graphical information, such as the coordinates of the various elements of the process definition (all graphical information is contained in the _BPMNDiagram_ tag in the XML, which is a child element of the _definitions_ tag). Save the following XML in a file named _holiday-request.bpmn20.xml_ in the _src/main/resources_ folder. [source,xml,linenums] ---- ---- Lines 2 to 11 look a bit daunting, but it's the same as you'll see in almost every process definition. It's kind of _boilerplate_ stuff that's needed to be fully compatible with the BPMN 2.0 standard specification. Every step (in BPMN 2.0 terminology, *'activity'*) has an _id_ attribute that gives it a unique identifier in the XML file. All _activities_ can have an optional name too, which increases the readability of the visual diagram, of course. The _activities_ are connected by a *sequence flow*, which is a directed arrow in the visual diagram. When executing a process instance, the execution will flow from the _start event_ to the next _activity_, following the _sequence flow_. The _sequence flows_ leaving the _exclusive gateway_ (the diamond shape with the X) are clearly special: both have a _condition_ defined in the form of an _expression_ (see line 25 and 32). When the process instance execution reaches this _gateway_, the _conditions_ are evaluated and the first that resolves to _true_ is taken. This is what the _exclusive_ stands for here: only one is selected. Other types of gateways are, of course, possible if different routing behavior is needed. The condition written here as an _expression_ is of the form _${approved}_, which is a shorthand for _${approved == true}_. The variable 'approved' is called a *process variable*. A _process variable_ is a persistent bit of data that is stored together with the process instance and can be used during the lifetime of the process instance. In this case, it does mean that we will have to set this _process variable_ at a certain point (when the manager user task is submitted or, in Flowable terminology, _completed_) in the process instance, as it's not data that is available when the process instance starts. Now we have the process BPMN 2.0 XML file, we next need to *'deploy'* it to the engine. _Deploying_ a process definition means that: * the process engine will store the XML file in the database, so it can be retrieved whenever needed * the process definition is parsed to an internal, executable object model, so that _process instances_ can be started from it. To _deploy_ a process definition to the Flowable engine, the _RepositoryService_ is used, which can be retrieved from the _ProcessEngine_ object. Using the _RepositoryService_, a new _Deployment_ is created by passing the location of the XML file and calling the _deploy()_ method to actually execute it: [source,java,linenums] ---- RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("holiday-request.bpmn20.xml") .deploy(); ---- We can now verify that the process definition is known to the engine (and learn a bit about the API) by querying it through the API. This is done by creating a new _ProcessDefinitionQuery_ object through the _RepositoryService_. [source,java,linenums] ---- ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .deploymentId(deployment.getId()) .singleResult(); System.out.println("Found process definition : " + processDefinition.getName()); ---- ==== Starting a process instance We now have the process definition _deployed_ to the process engine, so _process instances_ can be started using this _process definition_ as a 'blueprint'. To start the process instance, we need to provide some initial _process variables_. Typically, you'll get these through a form that is presented to the user or through a REST API when a process is triggered by something automatic. In this example, we'll keep it simple and use the java.util.Scanner class to simply input some data on the command line: [source,java,linenums] ---- Scanner scanner= new Scanner(System.in); System.out.println("Who are you?"); String employee = scanner.nextLine(); System.out.println("How many holidays do you want to request?"); Integer nrOfHolidays = Integer.valueOf(scanner.nextLine()); System.out.println("Why do you need them?"); String description = scanner.nextLine(); ---- Next, we can start a _process instance_ through the _RuntimeService_. The collected data is passed as a _java.util.Map_ instance, where the key is the identifier that will be used to retrieve the variables later on. The process instance is started using a _key_. This _key_ matches the _id_ attribute that is set in the BPMN 2.0 XML file, in this case _holidayRequest_. (NOTE: there are many ways you'll learn later on to start a process instance, beyond using a key) [source,xml] ---- ---- [source,java,linenums] ---- RuntimeService runtimeService = processEngine.getRuntimeService(); Map variables = new HashMap(); variables.put("employee", employee); variables.put("nrOfHolidays", nrOfHolidays); variables.put("description", description); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables); ---- When the process instance is started, an *execution* is created and put in the start event. From there, this _execution_ follows the sequence flow to the user task for the manager approval and executes the user task behavior. This behavior will create a task in the database that can be found using queries later on. A user task is a _wait state_ and the engine will stop executing anything further, returning the API call. ==== Sidetrack: transactionality In Flowable, database transactions play a crucial role to guarantee data consistency and solve concurrency problems. When you make a Flowable API call, by default, everything is synchronous and part of the same transaction. Meaning, when the method call returns, a transaction will be started and committed. When a process instance is started, there will be *one database transaction* from the start of the process instance to the next _wait state_. In this example, this is the first user task. When the engine reaches this user task, the state is persisted to the database and the transaction is committed and the API call returns. In Flowable, when continuing a process instance, there will always be one database transaction going from the previous _wait state_ to the next _wait state_. Once persisted, the data can be in the database for a long time, even years if it has to be, until an API call is executed that takes the process instance further. Note that no computing or memory resources are consumed when the process instance is in such a wait state, waiting for the next API call. In the example here, when the first user task is completed, one database transaction will be used to go from the user task through the exclusive gateway (the automatic logic) until the second user task. Or straight to the end with the other path. ==== Querying and completing tasks In a more realistic application, there will be a user interface where the employees and the managers can log in and see their task lists. With these, they can inspect the process instance data that is stored as _process variables_ and decide what they want to do with the task. In this example, we will mimic task lists by executing the API calls that normally would be behind a service call that drives a UI. We haven't yet configured the assignment for the user tasks. We want the first task to go the the 'managers' group and the second user task to be assigned to the original requester of the holiday. To do this, add the _candidateGroups_ attribute to the first task: [source,xml] ---- ---- and the _assignee_ attribute to the second task as shown below. Note that we're not using a static value like the 'managers' value above, but a dynamic assignment based on a process variable that we've passed when the process instance was started: [source,xml] ---- ---- To get the actual task list, we create a _TaskQuery_ through the _TaskService_ and we configure the query to only return the tasks for the 'managers' group: [source,java,linenums] ---- TaskService taskService = processEngine.getTaskService(); List tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list(); System.out.println("You have " + tasks.size() + " tasks:"); for (int i=0; i processVariables = taskService.getVariables(task.getId()); System.out.println(processVariables.get("employee") + " wants " + processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?"); ---- Which, if you run this, should look something like this: image::images/getting.started.console.logging3.png[align="center"] The manager can now *complete the task*. In reality, this often means that a form is submitted by the user. The data from the form is then passed as _process variables_. Here, we'll mimic this by passing a map with the 'approved' variable (the name is important, as it's used later on in the conditions of the sequence flow!) when the task is completed: [source,java,linenums] ---- boolean approved = scanner.nextLine().toLowerCase().equals("y"); variables = new HashMap(); variables.put("approved", approved); taskService.complete(task.getId(), variables); ---- The task is now completed and one of the two paths leaving the exclusive gateway is selected based on the 'approved' process variable. [[getting.started.delegate]] ==== Writing a JavaDelegate There is a last piece of the puzzle still missing: we haven't implemented the automatic logic that will get executed when the request is approved. In the BPMN 2.0 XML this is a *service task* and it looked above like: [source,xml] ---- ---- In reality, this logic could be anything, ranging from calling a service with HTTP REST, to executing some legacy code calls to a system the organization has been using for decades. We won't implement the actual logic here but simply log the _processing_. Create a new class (_File -> New -> Class_ in Eclipse), fill in _org.flowable_ as package name and _CallExternalSystemDelegate_ as class name. Make that class implement the _org.flowable.engine.delegate.JavaDelegate_ interface and implement the _execute_ method: [source,java,linenums] ---- package org.flowable; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; public class CallExternalSystemDelegate implements JavaDelegate { public void execute(DelegateExecution execution) { System.out.println("Calling the external system for employee " + execution.getVariable("employee")); } } ---- When the _execution_ arrives at the _service task_, the class that is referenced in the BPMN 2.0 XML is instantiated and called. When running the example now, the logging message is shown, demonstrating the custom logic is indeed executed: image::images/getting.started.console.logging4.png[align="center"] ==== Working with historical data One of the many reasons for choosing to use a process engine like Flowable is because it automatically stores *audit data* or *historical data* for all the process instances. This data allows the creation of rich reports that give insights into how the organization works, where the bottlenecks are, etc. For example, suppose we want to show the duration of the process instance that we've been executing so far. To do this, we get the _HistoryService_ from the _ProcessEngine_ and create a query for _historical activities_. In the snippet below you can see we add some additional filtering: * only the activities for one particular process instance * only the activities that have finished The results are also sorted by end time, meaning that we'll get them in execution order. [source,java,linenums] ---- HistoryService historyService = processEngine.getHistoryService(); List activities = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstance.getId()) .finished() .orderByHistoricActivityInstanceEndTime().asc() .list(); for (HistoricActivityInstance activity : activities) { System.out.println(activity.getActivityId() + " took " + activity.getDurationInMillis() + " milliseconds"); } ---- Running the example again, we now see something like this in the console: ---- startEvent took 1 milliseconds approveTask took 2638 milliseconds decision took 3 milliseconds externalSystemCall took 1 milliseconds ---- ==== Conclusion This tutorial introduced various Flowable and BPMN 2.0 concepts and terminology, while also demonstrating how to use the Flowable API programmatically. Of course, this is just the start of the journey. The following sections will dive more deeply into the many options and features that the Flowable engine supports. Other sections go into the various ways the Flowable engine can be set up and used, and describe in detail all the BPMN 2.0 constructs that are possible. [[getting.started.rest]] === Getting started with the Flowable REST API This section shows the same example as the <>: deploying a process definition, starting a process instance, getting a task list and completing a task. If you haven't read that section, it might be good to skim through it to get an idea of what is done there. This time, the Flowable REST API is used rather than the Java API. You'll soon notice that the REST API closely matches the Java API, and knowing one automatically means that you can find your way around the other. To get a full, detailed overview of the Flowable REST API, check out the <>. ==== Setting up the REST application When you download the .zip file from the flowable.org website, the REST application can be found in the _wars_ folder. You'll need a servlet container, such as link:$$http://tomcat.apache.org//$$[Tomcat], link:$$http://www.eclipse.org/jetty//$$[Jetty], and so on, to run the WAR file. When using Tomcat the steps are as follows: * Download and unzip the latest and greatest Tomcat zip file (choose the 'Core' distribution from the Tomcat website). * Copy the flowable-rest.war file from the _wars_ folder of the unzipped Flowable distribution to the _webapps_ folder of the unzipped Tomcat folder. * On the command line, go to the _bin_ folder of the Tomcat folder. * Execute '_./catalina run_' to boot up the Tomcat server. During the server boot up, you'll notice some Flowable logging messages passing by. At the end, a message like '_INFO [main] org.apache.catalina.startup.Catalina.start Server startup in xyz ms_' indicates that the server is ready to receive requests. Note that by default an in-memory H2 database instance is used, which means that data won't survive a server restart. In the following sections, we'll use cURL to demonstrate the various REST calls. All REST calls are by default protected with _basic authentication_. The user 'rest-admin' with password 'test' is used in all calls. After bootup, verify the application is running correctly by executing ---- curl --user rest-admin:test http://localhost:8080/flowable-rest/service/management/engine ---- If you get back a proper json response, the REST API is up and running. ==== Deploying a process definition The first step is to deploy a process definition. With the REST API, this is done by uploading a .bpmn20.xml file (or .zip file for multiple process definitions) as 'multipart/formdata': ---- curl --user rest-admin:test -F "file=@holiday-request.bpmn20.xml" http://localhost:8080/flowable-rest/service/repository/deployments ---- To verify that the process definition is deployed correctly, the list of process definitions can be requested: ---- curl --user rest-admin:test http://localhost:8080/flowable-rest/service/repository/process-definitions ---- which returns a list of all process definitions currently deployed to the engine. ==== Start a process instance Starting a process instance through the REST API is similar to doing the same through the Java API: a _key_ is provided to identify the process definition to use along with a map of initial process variables: ---- curl --user rest-admin:test -H "Content-Type: application/json" -X POST -d '{ "processDefinitionKey":"holidayRequest", "variables": [ { "name":"employee", "value": "John Doe" }, { "name":"nrOfHolidays", "value": 7 }]}' http://localhost:8080/flowable-rest/service/runtime/process-instances ---- which returns something like ---- {"id":"43","url":"http://localhost:8080/flowable-rest/service/runtime/process-instances/43","businessKey":null,"suspended":false,"ended":false,"processDefinitionId":"holidayRequest:1:42","processDefinitionUrl":"http://localhost:8080/flowable-rest/service/repository/process-definitions/holidayRequest:1:42","activityId":null,"variables":[],"tenantId":"","completed":false} ---- ==== Task list and completing a task When the process instance is started, the first task is assigned to the 'managers' group. To get all tasks for this group, a task query can be done through the REST API: ---- curl --user rest-admin:test -H "Content-Type: application/json" -X POST -d '{ "candidateGroup" : "managers" }' http://localhost:8080/flowable-rest/service/query/tasks ---- which returns a list of all tasks for the 'managers' group Such a task can now be completed using: ---- curl --user rest-admin:test -H "Content-Type: application/json" -X POST -d '{ "action" : "complete", "variables" : [ { "name" : "approved", "value" : true} ] }' http://localhost:8080/flowable-rest/service/runtime/tasks/25 ---- However, you most likely will get an error like: ---- {"message":"Internal server error","exception":"couldn't instantiate class org.flowable.CallExternalSystemDelegate"} ---- This means that the engine couldn't find the _CallExternalSystemDelegate_ class that is referenced in the service task. To solve this, the class needs to be put on the classpath of the application (which will require a restart). Create the class as described in <>, package it up as a JAR and put it in the _WEB-INF/lib_ folder of the flowable-rest folder under the _webapps_ folder of Tomcat.