Flowable applications
Flowable provides the flowable-rest.war
which contains the Flowable REST API. More about this can be read in the REST API chapter.
The application is a Spring Boot 3.1 based application, which means that the WAR file is actually executable and can be run as a normal standalone application. See The Executable Jar Format in the Spring Boot reference documentation.
Flowable REST application installation
As mentioned before, the application can be deployed on a Tomcat server, and to get started this is probably the easiest approach when additional configuration settings are used. For this installation guide we’ll describe the installation of the application in a Tomcat server.
Download a recent stable version of Apache Tomcat. It has to be Jakarta Servlet 6 compliant (Tomcat 10 or later)
Download the latest stable Flowable 7 version.
Copy the flowable-rest.war file from the Flowable distribution wars folder to the Tomcat webapps folder.
Startup the Tomcat server by running the bin/startup.sh (Mac OS and Linux) or bin/startup.bat (Windows) script.
Open a web browser and go to http://localhost:8080/flowable-rest/docs.
The Flowable REST application should now be running with an H2 in-memory database and the Swagger Docs should be shown in your web browser:
The Flowable REST application should now be running with an H2 in-memory database
Usually, you will want to change the default H2 in-memory database configuration to a MySQL or Postgres (or other persistent database) configuration. You can do this by changing the application.properties file in the WEB-INF/classes/ directory of the application. However, it is easier to use the Spring Boot Externalized Configuration. An example configuration can be found on Github To change the default configuration to MySQL the following changes are needed to the properties file:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/flowable?characterEncoding=UTF-8
spring.datasource.username=flowable
spring.datasource.password=flowable
This configuration will expect a flowable database to be present in the MySQL server and the REST app will automatically generate the necessary database tables. For Postgres the following changes are necessary:
spring.datasource.url=jdbc:postgresql://localhost:5432/flowable
spring.datasource.username=flowable
spring.datasource.password=flowable
In addition to changing the configuration, make sure the database driver is available on the classpath. Again, you could do this for the web application by adding the driver JAR file to the WEB-INF/lib folder, but you can also copy the JAR file to the Tomcat lib folder. For MySQL and Postgres the database drivers can be downloaded from:
Postgres: https://jdbc.postgresql.org/
When running the REST as a standalone application the database driver can be added by using the loader.path
property.
java -Dloader.path=/location/to/your/driverfolder -jar flowable-rest.war
See the PropertiesLauncher
Features in the Spring Boot reference documentation for more information.
Flowable REST Application Configuration
As the Flowable REST app is a Spring Boot application, you can use all the properties Spring Boot provides. In order to provide custom configuration for the application have a look at the Externalized Configuration section of the Spring Boot documentation.
You can also use YAML based properties.
Property name | Old Property | Default value | Description |
---|---|---|---|
flowable.rest.app.authentication-mode |
rest.authentication.mode |
verify-privilege |
Configures the way user credentials are verified when doing a REST API call: 'any-user' : the user needs to exist and the password need to match. Any user is allowed to do the call (this is the pre 6.3.0 behavior) 'verify-privilege' : the user needs to exist, the password needs to match and the user needs to have the 'rest-api' privilege If nothing set, defaults to 'verify-privilege' |
Some of the old properties have been moved to be managed by the Flowable Spring Boot starter (or Spring Boot itself)
Property name | Old Property | Default value | Description |
---|---|---|---|
flowable.async-executor-activate |
engine.process.asyncexecutor.activate |
true |
Whether the async executor should be activated. |
flowable.database-schema-update |
engine.process.schema.update |
true |
The strategy that should be used for the database schema. |
flowable.history-level |
engine.process.history.level |
- |
The history level that needs to be used. |
flowable.process.servlet.name |
flowable.rest-api-servlet-name |
Flowable BPMN Rest API |
The name of the Process servlet. |
flowable.process.servlet.path |
flowable.rest-api-mapping |
/process-api |
The context path for the Process rest servlet. |
flowable.idm.enabled |
flowable.db-identity-used |
true |
Whether the idm engine needs to be started. |
flowable.idm.password-encoder |
security.passwordencoder |
- |
The type of the password encoder that needs to be used. |
flowable.idm.ldap.base-dn |
ldap.basedn |
- |
The base 'distinguished name' (DN) from which the searches for users and groups are started. Use 'user-base-dn' or 'group-base-dn' when needing to differentiate between user and group base DN. |
flowable.idm.ldap.enabled |
ldap.enabled |
false |
Whether to enable LDAP IDM Service. |
flowable.idm.ldap.password |
ldap.password |
- |
The password that is used to connect to the LDAP system. |
flowable.idm.ldap.port |
ldap.port |
-1 |
The port on which the LDAP system is running. |
flowable.idm.ldap.server |
ldap.server |
- |
The server host on which the LDAP system can be reached. For example 'ldap://localhost'. |
flowable.idm.ldap.user |
ldap.user |
- |
The user id that is used to connect to the LDAP system. |
flowable.idm.ldap.attribute.email |
ldap.attribute.email |
- |
Name of the attribute that matches the user email. This property is used when looking for an 'org.flowable.idm.api.User' object and the mapping between the LDAP object and the Flowable 'org.flowable.idm.api.User' object is done. |
flowable.idm.ldap.attribute.first-name |
ldap.attribute.firstname |
- |
Name of the attribute that matches the user first name. This property is used when looking for a 'org.flowable.idm.api.User' object and the mapping between the LDAP object and the Flowable 'org.flowable.idm.api.User' object is done. |
flowable.idm.ldap.attribute.group-id |
ldap.attribute.groupid |
- |
Name of the attribute that matches the group id. This property is used when looking for a 'org.flowable.idm.api.Group' object and the mapping between the LDAP object and the Flowable 'org.flowable.idm.api.Group' object is done. |
flowable.idm.ldap.attribute.group-name |
ldap.attribute.groupname |
- |
Name of the attribute that matches the group name. This property is used when looking for a 'org.flowable.idm.api.Group' object and the mapping between the LDAP object and the Flowable 'org.flowable.idm.api.Group' object is done. |
flowable.idm.ldap.attribute.last-name |
ldap.attribute.lastname |
- |
Name of the attribute that matches the user last name. This property is used when looking for a 'org.flowable.idm.api.User' object and the mapping between the LDAP object and the Flowable 'org.flowable.idm.api.User' object is done. |
flowable.idm.ldap.attribute.user-id |
ldap.attribute.userid |
- |
Name of the attribute that matches the user id. This property is used when looking for a 'org.flowable.idm.api.User' object and the mapping between the LDAP object and the Flowable 'org.flowable.idm.api.User' object is done. This property is optional and is only needed if searching for 'org.flowable.idm.api.User' objects using the Flowable API. |
flowable.idm.ldap.cache.group-size |
ldap.cache.groupsize |
-1 |
Allows to set the size of the 'org.flowable.ldap.LDAPGroupCache'. This is an LRU cache that caches groups for users and thus avoids hitting the LDAP system each time the groups of a user needs to be known. The cache will not be instantiated if the value is less then zero. By default set to -1, so no caching is done. Note that the group cache is instantiated on the 'org.flowable.ldap.LDAPIdentityServiceImpl'. As such, if you have a custom implementation of the 'org.flowable.ldap.LDAPIdentityServiceImpl', do not forget to add the group cache functionality. |
flowable.idm.ldap.query.all-groups |
ldap.query.groupall |
- |
The query that is executed when searching for all groups. |
flowable.idm.ldap.query.all-users |
ldap.query.userall |
- |
The query that is executed when searching for all users. |
flowable.idm.ldap.query.groups-for-user |
ldap.query.groupsforuser |
- |
The query that is executed when searching for the groups of a specific user.
For example: |
flowable.idm.ldap.query.user-by-full-name-like |
ldap.query.userbyname |
- |
The query that is executed when searching for a user by full name.
For example: |
flowable.idm.ldap.query.user-by-id |
ldap.query.userbyid |
- |
The query that is executed when searching for a user by userId.
For example: |
flowable.mail.server.host |
email.host |
localhost |
The host of the mail server. |
flowable.mail.server.password |
email.password |
- |
The password for the mail server authentication. |
flowable.mail.server.port |
email.port |
1025 |
The port of the mail server. |
flowable.mail.server.ssl-port |
email.ssl-port |
1465 |
The SSL port of the mail server. |
flowable.mail.server.use-ssl |
email.use-ssl |
false |
Sets whether SSL/TLS encryption should be enabled for the SMTP transport upon connection (SMTPS/POPS). |
flowable.mail.server.use-tls |
email.use-tls |
false |
Set or disable the STARTTLS encryption. |
flowable.mail.server.username |
email.username |
- |
The username that needs to be used for the mail server authentication. If empty no authentication would be used. |
flowable.process.definition-cache-limit |
flowable.process-definitions.cache.max |
-1 |
The maximum amount of process definitions available in the process definition cache. Per default it is -1 (all process definitions). |
Property name | Old Property | Default value | Description |
---|---|---|---|
spring.datasource.driver-class-name |
datasource.driver |
- |
Fully qualified name of the JDBC driver. Auto-detected based on the URL by default. |
spring.datasource.jndi-name |
datasource.jndi.name |
- |
JNDI location of the datasource. Class, url, username & password are ignored when set. |
spring.datasource.password |
datasource.password |
- |
Login password of the database. |
spring.datasource.url |
datasource.url |
- |
JDBC URL of the database. |
spring.datasource.username |
datasource.username |
- |
Login username of the database. |
spring.datasource.hikari.connection-test-query |
datasource.preferred-test-query |
- |
The SQL query to be executed to test the validity of connections. |
spring.datasource.hikari.connection-timeout |
datasource.connection.timeout |
- |
The maximum number of milliseconds that a client will wait for a connection from the pool. If this time is exceeded without a connection becoming available, a SQLException will be thrown when getting a connection. |
spring.datasource.hikari.idle-timeout |
datasource.connection.idletimeout |
- |
The maximum amount of time (in milliseconds) that a connection is allowed to sit idle in the pool. Whether a connection is retired as idle or not is subject to a maximum variation of +30 seconds, and average variation of +15 seconds. A connection will never be retired as idle before this timeout. A value of 0 means that idle connections are never removed from the pool. |
spring.datasource.hikari.max-lifetime |
datasource.connection.maxlifetime |
- |
This property controls the maximum lifetime of a connection in the pool. When a connection reaches this timeout, even if recently used, it will be retired from the pool. An in-use connection will never be retired, only when it is idle will it be removed. |
spring.datasource.hikari.maximum-pool-size |
datasource.connection.maxpoolsize |
- |
The property controls the maximum size that the pool is allowed to reach, including both idle and in-use connections. Basically this value will determine the maximum number of actual connections to the database backend. When the pool reaches this size, and no idle connections are available, calls to getConnection() will block for up to connectionTimeout milliseconds before timing out. |
spring.datasource.hikari.minimum-idle |
datasource.connection.minidle |
- |
The property controls the minimum number of idle connections that HikariCP tries to maintain in the pool, including both idle and in-use connections. If the idle connections dip below this value, HikariCP will make a best effort to restore them quickly and efficiently. |
spring.servlet.multipart.max-file-size |
file.upload.max.size |
10MB |
Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or kilobytes, respectively. |
Flowable LDAP configuration
In addition to the default identity tables, the IDM component can also be configured to use an LDAP server. To connect to a LDAP server, additional properties in the application.properties file (or any other way of configuring the application) are needed:
#
# LDAP
#
flowable.idm.ldap.enabled=true
flowable.idm.ldap.server=ldap://localhost
flowable.idm.ldap.port=10389
flowable.idm.ldap.user=uid=admin, ou=system
flowable.idm.ldap.password=secret
flowable.idm.ldap.base-dn=o=flowable
flowable.idm.ldap.query.user-by-id=(&(objectClass=inetOrgPerson)(uid={0}))
flowable.idm.ldap.query.user-by-full-name-like=(&(objectClass=inetOrgPerson)(|({0}=*{1}*)({2}=*{3}*)))
flowable.idm.ldap.query.all-users=(objectClass=inetOrgPerson)
flowable.idm.ldap.query.groups-for-user=(&(objectClass=groupOfUniqueNames)(uniqueMember={0}))
flowable.idm.ldap.query.all-groups=(objectClass=groupOfUniqueNames)
flowable.idm.ldap.query.group-by-id=(&(objectClass=groupOfUniqueNames)(uniqueId={0}))
flowable.idm.ldap.attribute.user-id=uid
flowable.idm.ldap.attribute.first-name=cn
flowable.idm.ldap.attribute.last-name=sn
flowable.idm.ldap.attribute.group-id=cn
flowable.idm.ldap.attribute.group-name=cn
flowable.idm.ldap.cache.group-size=10000
flowable.idm.ldap.cache.group-expiration=180000
When the flowable.idm.ldap.enabled
property is set to true, the REST app will expect the other LDAP properties to have been filled-in.
In this example configuration the server configuration + LDAP queries for the Apache Directory Server are provided.
For other LDAP servers, like Active Directory, other configuration values are needed.
When LDAP is configured, authentication and group retrieval for a user will be done through the LDAP server. Only privileges will still be retrieved from the Flowable identity tables. So make sure each LDAP user has the correct privileges defined in the IDM app.
If the application is booted with LDAP configuration the bootstrap logic will check if there are already privileges present in the Flowable identity tables.
If there are no privileges (only when booting the first time), the 4 default privileges will be created and the flowable.rest.app.admin.user-id
property value (from application.properties or configured in the environment) will be used as the user id to get all privileges.
So make sure that the flowable.rest.app.admin.user-id
property value is set to a valid LDAP user, otherwise nobody will be able to use the Flowable REST app.
Production-ready endpoints
The Production ready endpoints from Spring Boot are present for the application. To have an overview of all the available Endpoints have a look at the Actuator Web API Documentation.
This properties are set per default:
# Expose all actuator endpoints to the web
# They are exposed, but only authenticated users can see /info and /health abd users with access-admin can see the others
management.endpoints.web.exposure.include=*
# Full health details should only be displayed when a user is authorized
management.endpoint.health.show-details=when_authorized
# Only users with role access-admin can access full health details
management.endpoint.health.roles=access-admin
The security is configured in such way that the info
and health
endpoint are exposed to all authenticated users.
Full details of the health
endpoint can only be seen by users with the privilege access-admin
.
In case you want to change that you need to configure management.endpoint.health.show-details
.
All the rest of the endpoints are accessing only to users with the access-admin
privilege.
Custom bean deployment
There are multiple ways of providing custom beans to the Flowable application.
Using Spring Boot auto configuration
The Flowable application is a Spring Boot 2 application. This means that normal Spring Boot auto configuration can be used to make the beans to Flowable. This can be done in the following manner
package com.your.own.package.configuration;
@Configuration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE) // Makes sure that this configuration will be processed last by Spring Boot
@ConditionalOnBean(type = "org.flowable.engine.ProcessEngine") // The configuration will only be used when the ProcessEngine bean is present
public class YourOwnConfiguration {
@Configuration
@ComponentScan ("com.your.own.package.beans")
public static class ComponentScanConfiguration {
// This class is needed in order to conditionally perform the component scan (i.e. when the ProcessEngine bean is present)
// It is an optional class, in case you don't need component scanning then you don't need to do this
}
@Bean
public CustomBean customBean() {
// create your bean
}
@Bean
public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> customProcessEngineConfigurationConfigurer() {
return engineConfiguration -> {
// You can use this to add extra configuration to the process engine
}
}
}
Note that when using Spring Boot the configuration class can be under your own package and not under some Flowable package.
In order to make this class an auto configuration class a file named org.springframework.boot.autoconfigure.AutoConfiguration.imports
should be created in the META-INF/spring
folder of your jar.
In this file you should add
com.your.own.package.configuration.YourOwnCustomConfiguration
In order to use this approach you would need to include your jar in the WEB-INF/lib
folder of the exploded war.
Placing this jar in the lib folder of the servlet container (e.g. Tomcat) is not going to work due to the way Spring proxies the @Configuration
classes.
Component scan
Another way to provide custom Spring beans to the Flowable engine is to put them under a certain package and have the Flowable application component scan that package. Based on the application used, this package is different:
org.flowable.rest.app
for theflowable-rest.war
The custom beans can be located in a single JAR and this jar should be present on the classpath when the application is starting up.
Depending where there JAR is placed, the lib folder of the servlet container (e.g. Tomcat) or the WEB-INF/lib
folder of the exploded war, there are different possibilities.
When using the lib folder of the servlet container then the created classes should be self contained, i.e. they should only use classes from within the jar.
You can use any of the Spring @Component
annotations (with the exception of @Configuration
).
The reason for not being able to use @Configuration
classes is the fact that each configuration class is proxied by Spring with the help of the ConfigurationClassPostProcessor
.
However, the classloader loading the @Configuration
class does not have access to the needed classes by Spring.
When including the jar in the WEB-INF/lib
folder of the exploded war then @Configuration
classes and dependencies to other jars is possible.
Creating your own Spring Boot application
This approach is the most flexible and most powerful approach of all. In order to follow this approach have a look at the Getting Started with Spring Boot section of this documentation.