{"id":471,"date":"2020-06-27T17:06:06","date_gmt":"2020-06-27T17:06:06","guid":{"rendered":"http:\/\/www.canchito-dev.com\/public\/blog\/?p=471"},"modified":"2021-05-02T13:36:51","modified_gmt":"2021-05-02T13:36:51","slug":"flowable-custom-engine-configuration","status":"publish","type":"post","link":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/27\/flowable-custom-engine-configuration\/","title":{"rendered":"Customizing Flowable Engine"},"content":{"rendered":"<div class=\"perfect-pullquote vcard pullquote-align-full pullquote-border-placement-left\"><blockquote><p><\/p>\n<p>In this article, we will go into detail on how to customize Flowable&#8217;s engine. Three changes to the engine will be done:<\/p>\n<ol>\n<li>Change the database connection by modifying the data source and adding custom data source properties.<\/li>\n<li>Use a strong UUID generator.<\/li>\n<li>Implement a custom event handler.<\/li>\n<\/ol>\n<p><\/p><\/blockquote><\/div>\n<div>\n  <a class=\"donate-with-crypto\"\n     href=\"https:\/\/commerce.coinbase.com\/checkout\/faf64f90-2e80-46ee-aeba-0fde14cbeb46\"><br \/>\n    Buy Me a Coffee<br \/>\n  <\/a><br \/>\n  <script src=\"https:\/\/commerce.coinbase.com\/v1\/checkout.js?version=201807\">\n  <\/script>\n<\/div>\n<h2>Contribute Code<\/h2>\n<p style=\"text-align: justify;\">If you would like to become an active contributor to this project please follow these simple steps:<\/p>\n<ol>\n<li>Fork it<\/li>\n<li>Create your feature branch<\/li>\n<li>Commit your changes<\/li>\n<li>Push to the branch<\/li>\n<li>Create new Pull Request<\/li>\n<\/ol>\n<h2>What you\u2019ll need<\/h2>\n<ul>\n<li>About 40 minutes<\/li>\n<li>A favorite IDE. In this post, we use <a href=\"https:\/\/www.jetbrains.com\/idea\/download\/index.html\">Intellij Community<\/a><\/li>\n<li><a href=\"http:\/\/www.oracle.com\/technetwork\/java\/javase\/downloads\/index.html\">JDK 7<\/a> or later. It can be made to work with JDK6, but it will need configuration tweaks. Please check the Spring Boot documentation<\/li>\n<\/ul>\n<h2>Starting with Spring Initializr<\/h2>\n<p style=\"text-align: justify;\">For all Spring applications, it is always a good idea to start with the <a href=\"https:\/\/start.spring.io\/\">Spring Initializr<\/a>. The Initializr is an excellent option for pulling in all the dependencies you need for an application and does a lot of the setup for you. This example needs only the Spring Web, and H2 Database dependency. The following image shows the Initializr set up for this sample project:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large\" src=\"http:\/\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr-1024x674.png\" alt=\"CANCHITO-DEV: Spring Initializr\" width=\"625\" height=\"411\" \/><\/p>\n<p>The following listing shows the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">pom.xml<\/code> file that is created when you choose Maven:<\/p>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;?xml\u00a0version=\"1.0\"\u00a0encoding=\"UTF-8\"?&gt;\u00a0\u00a0\r\n&lt;project\u00a0xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"\u00a0xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\u00a0xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0\u00a0https:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;parent&gt;\u00a0&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;version&gt;2.2.7.RELEASE&lt;\/version&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;relativePath\/&gt;\u00a0&lt;!--\u00a0lookup\u00a0parent\u00a0from\u00a0repository\u00a0--&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/parent&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;com.canchitodev.example&lt;\/groupId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;flowable-custom-engine-configuration&lt;\/artifactId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;packaging&gt;war&lt;\/packaging&gt;\u00a0\u00a0\r\n\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;name&gt;flowable-custom-engine-configuration&lt;\/name&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;description&gt;Demo\u00a0project\u00a0for\u00a0Spring\u00a0Boot\u00a0using\u00a0Flowable\u00a0BPM&lt;\/description&gt;\u00a0\u00a0\r\n\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;organization&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;name&gt;Canchito\u00a0Development&lt;\/name&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;url&gt;http:\/\/www.canchito-dev.com&lt;\/url&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/organization&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;issueManagement&gt;\u00a0\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;system&gt;Canchito Development&lt;\/system&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;url&gt;https:\/\/github.com\/canchito-dev\/spring-flowable-integration\/issues&lt;\/url&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/issueManagement&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;url&gt;https:\/\/github.com\/canchito-dev\/spring-flowable-integration&lt;\/url&gt;\r\n\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;properties&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;project.reporting.outputEncoding&gt;UTF-8&lt;\/project.reporting.outputEncoding&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;java.version&gt;1.8&lt;\/java.version&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;flowable.version&gt;6.5.0&lt;\/flowable.version&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/properties&gt;\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;dependencies&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container --&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;dependency&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/dependency&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container --&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- H2 Database Engine --&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;dependency&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;com.h2database&lt;\/groupId&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;h2&lt;\/artifactId&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;scope&gt;runtime&lt;\/scope&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/dependency&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- H2 Database Engine --&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web --&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;dependency&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;spring-boot-starter-tomcat&lt;\/artifactId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/dependency&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web --&gt;\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- Starter for testing Spring Boot applications with libraries including JUnit, Hamcrest and Mockito --&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;dependency&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;scope&gt;test&lt;\/scope&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;exclusions&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;exclusion&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;org.junit.vintage&lt;\/groupId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;junit-vintage-engine&lt;\/artifactId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/exclusion&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/exclusions&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/dependency&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!-- Starter for testing Spring Boot applications with libraries including JUnit, Hamcrest and Mockito --&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/dependencies&gt;\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;build&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;plugins&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;plugin&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/plugin&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/plugins&gt;\u00a0\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/build&gt;\u00a0\u00a0\r\n&lt;\/project&gt;<\/pre>\n<\/div>\n<h2>Adding Flowable&#8217;s Dependencies<\/h2>\n<p style=\"text-align: justify;\">Now, simply add <em>flowable-spring-boot-starter<\/em> dependency. This will add all the engines.<\/p>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;!--\u00a0Flowable\u00a0Spring\u00a0Boot\u00a0Starter\u00a0Basic\u00a0--&gt;\r\n&lt;dependency&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;groupId&gt;org.flowable&lt;\/groupId&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;artifactId&gt;flowable-spring-boot-starter-basic&lt;\/artifactId&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;version&gt;${flowable.version}&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;!--\u00a0Flowable\u00a0Spring\u00a0Boot\u00a0Starter\u00a0Basic\u00a0--&gt;<\/pre>\n<\/div>\n<p style=\"text-align: justify;\">That\u2019s all that\u2019s needed. This dependency will transitively add the correct Flowable dependencies to the classpath. You can now run your Spring Boot application.<\/p>\n<h2>Customizing Engine Configuration<\/h2>\n<p style=\"text-align: justify;\">It is very easy to change and customize the engine configuration, simple by implementing the interface <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">org.flowable.spring.boot.EngineConfigurationConfigurer&lt;T&gt;<\/code>. Where <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">T<\/code> is the Spring Type of the particular Engine Configuration. This can be useful for advanced configuration settings or simply because a property has not been exposed (yet).<\/p>\n<p style=\"text-align: justify;\">By exposing an instance of this class as an <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> in the Spring Boot configuration, the instance will be called before the process engine is fully created.<\/p>\n<p style=\"text-align: justify;\">So, let&#8217;s first create the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> that will expose the engine configuration. Create a class called <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">CustomEngineConfiguration<\/code>. The code should look like the following code sniff:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Primary  \r\n@Configuration  \r\n@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)\r\n@AutoConfigureAfter(ProcessEngineAutoConfiguration.class)  \r\npublic class CustomEngineConfiguration {\r\n  @Bean\r\n  EngineConfigurationConfigurer&lt;SpringProcessEngineConfiguration&gt; engineConfigurationConfigurer() {\r\n    return engineConfiguration -&gt; {};\r\n  }\r\n}<\/pre>\n<p style=\"text-align: justify;\">Note that we have added <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@AutoConfigureOrder<\/code> annotation so that Spring framework can order the classes among themselves without affecting the order of configuration classes; and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@AutoConfigureAfter<\/code> annotation which tell the framework that this configuration should be applied after other specified auto-configuration classes.<\/p>\n<p style=\"text-align: justify;\">This should be enough to create a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> that let&#8217;s you modify and customize the engine. Now let&#8217;s continue and customize the database connection using custom data properties.<\/p>\n<h2 style=\"text-align: justify;\">Custom Data Source<\/h2>\n<p style=\"text-align: justify;\">By default, you can easily change the data source configuration using Spring Boot data source properties. But we do not just want to change the connection string or the user credentials. We want to change other properties such as the connection pool size, its name, etc. Open the <code>application.properties<\/code> file and add the following properties:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">flowable.datasource.username=flowable  \r\nflowable.datasource.password=flowable  \r\nflowable.datasource.url=jdbc:h2:~\/flowable-db\/db  \r\nflowable.datasource.driver-class-name=org.h2.Driver  \r\nflowable.datasource.connection-timeout=60000  \r\nflowable.datasource.connection-test-query=SELECT 1  \r\nflowable.datasource.pool-name=flowable-db-pool  \r\nflowable.datasource.maximum-pool-size=15  \r\nflowable.datasource.minimum-idle=5  \r\nflowable.datasource.max-lifetime=60001  \r\nflowable.datasource.idle-timeout=60002<\/pre>\n<p style=\"text-align: justify;\">Next, go to the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">CustomEngineConfiguration<\/code> class and add a new <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> which will load the newly created properties into <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">DataSourceProperties<\/code> base class for configuration of a data source.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Primary  \r\n@Bean  \r\n@ConfigurationProperties(\"flowable.datasource\")  \r\npublic DataSourceProperties flowableDataSourceProperties() {  \r\n  return new DataSourceProperties();  \r\n}<\/pre>\n<p>Right below this <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code>, add a new one, which will create an instance of the data source. Note that we are using the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Qualifier<\/code> annotation for specifying which properties <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> should be used.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Primary  \r\n@Bean  \r\npublic HikariDataSource flowableDataSource(  \r\n      @Qualifier(\"flowableDataSourceProperties\") DataSourceProperties flowableDataSourceProperties  \r\n) {  \r\n   return flowableDataSourceProperties  \r\n         .initializeDataSourceBuilder()  \r\n         .type(HikariDataSource.class)  \r\n         .build();  \r\n}<\/pre>\n<p>Finally, change the engine to use the recently created data source <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> for connecting to the database. The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">EngineConfigurationConfigurer<\/code> <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> should look something like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean\r\nEngineConfigurationConfigurer&lt;SpringProcessEngineConfiguration&gt; engineConfigurationConfigurer(\r\n  @Qualifier(\"flowableDataSource\") DataSource dataSource\r\n) {\r\n  return engineConfiguration -&gt; {\r\n    engineConfiguration.setDataSource(dataSource);\r\n  };\r\n}<\/pre>\n<p style=\"text-align: justify;\">Again, we have passed the data source that we want to use, and annotated it with <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Qualifier<\/code> so that Spring know exactly which <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> to use. Very simple right!?<\/p>\n<h2 style=\"text-align: justify;\">Strong UUID ID generator for high concurrency<\/h2>\n<p style=\"text-align: justify;\">Each engine has a default ID generator. This generator reserves a block of IDs in the database, so that no other engine can use them. While the engine is performing operations at runtime, when the default ID generator notices that there are no more available IDs, a new transaction is started to fetch new ones. In some high concurrency cases with a heavy load of request to the ID generator, the default ID generator may cause exceptions due to not being able to fetch new ID blocks quickly enough.<\/p>\n<p style=\"text-align: justify;\">The alternative to the default ID generator is the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">org.flowable.engine.impl.persistence.StrongUuidGenerator<\/code>, which generates a unique <a href=\"http:\/\/en.wikipedia.org\/wiki\/Universally_unique_identifier\">UUID<\/a> locally and uses that as an identifier for all entities. Since the UUID is generated without the need for database access, it copes better with very high concurrency use cases. To use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">StrongUuidGenerator<\/code>, simply add it to the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">EngineConfigurationConfigurer<\/code> <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> as follow:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean\r\nEngineConfigurationConfigurer&lt;SpringProcessEngineConfiguration&gt; engineConfigurationConfigurer(\r\n  @Qualifier(\"flowableDataSource\") DataSource dataSource\r\n) {\r\n  return engineConfiguration -&gt; {\r\n    engineConfiguration.setDataSource(dataSource);\r\n\r\n    \/**  \r\n     * Flowable DOCS (v6.5.0)'s user guide - UUID ID generator for high concurrency \r\n     * https:\/\/flowable.com\/open-source\/docs\/bpmn\/ch18-Advanced\/#uuid-id-generator-for-high-concurrency\r\n     **\/\r\n    engineConfiguration.setIdGenerator(new StrongUuidGenerator());\r\n  };\r\n}<\/pre>\n<h2 style=\"text-align: justify;\">Custom Event handlers<\/h2>\n<p style=\"text-align: justify;\">Flowable&#8217;s engine event mechanism notifies you when various events occur within the engine. It\u2019s possible to register a listener for certain types of events as opposed to getting notified when any type of event is dispatched.<\/p>\n<p style=\"text-align: justify;\">You can either:<br \/>\n&#8211; add engine-wide event listeners <a href=\"https:\/\/flowable.com\/open-source\/docs\/bpmn\/ch03-Configuration#configuration-and-setup\">through the configuration<\/a>,<br \/>\n&#8211; add engine-wide event listeners <a href=\"https:\/\/flowable.com\/open-source\/docs\/bpmn\/ch03-Configuration#adding-listeners-at-runtime\">at runtime using the API<\/a> or<br \/>\n&#8211; add event-listeners to <a href=\"https:\/\/flowable.com\/open-source\/docs\/bpmn\/ch03-Configuration#adding-listeners-to-process-definitions\">specific process definitions in the BPMN XML<\/a><\/p>\n<p style=\"text-align: justify;\">For our example, we will add engine-wide event listeners <a href=\"https:\/\/flowable.com\/open-source\/docs\/bpmn\/ch03-Configuration#configuration-and-setup\">through the configuration<\/a>.<\/p>\n<p style=\"text-align: justify;\">First create a class with the name <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">CustomEventHandler<\/code>. The only requirement for an event-listener is to implement <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">org.flowable.engine.delegate.event.FlowableEventListener<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">public class CustomEventHandler implements FlowableEventListener {\r\n\r\n  private static final Logger log = LogManager.getLogger(CustomEventHandler.class);\r\n\r\n  @Override  \r\n  public void onEvent(FlowableEvent event) {  \r\n    switch ((FlowableEngineEventType) event.getType()) {\r\n      case PROCESS_STARTED:\r\n        log.info(event.toString());  \r\n        break;  \r\n      case PROCESS_COMPLETED:  \r\n        log.info(event.toString());  \r\n        break;\r\n    }\r\n  }\r\n\r\n  @Override  \r\n  public boolean isFailOnException() {\r\n    return false;\r\n  }\r\n\r\n  @Override  \r\n  public String getOnTransaction() {  \r\n     return null;  \r\n  }\r\n\r\n  @Override  \r\n  public boolean isFireOnTransactionLifecycleEvent() {  \r\n     return false;  \r\n  }\r\n}<\/pre>\n<p style=\"text-align: justify;\">For our example, we are logging in the console the events fired by Flowable&#8217;s engine whenever a process is started or completed.<\/p>\n<p style=\"text-align: justify;\">We will not go into details on what each of the overridden method do. If you have doubts about them, please leave a comment and we will gladly give you a hand.<\/p>\n<p style=\"text-align: justify;\">Once we have this class, we need to tell the engine there is a new event handler, by registering it. To do so, simply add it to the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">EngineConfigurationConfigurer<\/code> <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean<\/code> as follow:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Bean\r\nEngineConfigurationConfigurer&lt;SpringProcessEngineConfiguration&gt; engineConfigurationConfigurer(\r\n  @Qualifier(\"flowableDataSource\") DataSource dataSource\r\n) {\r\n  return engineConfiguration -&gt; {\r\n    engineConfiguration.setDataSource(dataSource);\r\n\r\n    engineConfiguration.setIdGenerator(new StrongUuidGenerator());\r\n\r\n    \/**  \r\n     * Flowable DOCS (v6.5.0)'s user guide - Event handlers * https:\/\/flowable.com\/open-source\/docs\/bpmn\/ch03-Configuration\/#event-handlers\r\n     **\/\r\n     engineConfiguration.setEventListeners(Arrays.&lt;FlowableEventListener&gt;asList(new CustomEventHandler()));\r\n  };\r\n}<\/pre>\n<p>If you execute a process, in the console you will see a log line as the one shown here whenever a process is started or completed:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">2020-06-08 09:49:18.153  INFO 18397 --- [ main] c.c.c.configuration.CustomEventHandler   : class org.flowable.engine.delegate.event.impl.FlowableProcessStartedEventImpl - PROCESS_STARTED\r\n2020-06-08 09:49:18.395  INFO 18397 --- [ main] c.c.c.configuration.CustomEventHandler   : class org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl - PROCESS_COMPLETED<\/pre>\n<h2 style=\"text-align: justify;\">Summary<\/h2>\n<p style=\"text-align: justify;\">In this post, we have shown how to customize Flowable&#8217;s engine by performing three changes: change the database connection by modifying the data source and adding custom data source properties; use a strong UUID generator; and implementing a custom event handler.<\/p>\n<p style=\"text-align: justify;\">We hope that, even though this was a very basic introduction, you understood how to customize the engine. We will try to go deeper into Flowable in upcoming posts. Please feel free to contact us. We will gladly response to any doubt or question you might have.<\/p>\n<p style=\"text-align: justify;\">Source code can be found in our <a href=\"https:\/\/github.com\/canchito-dev\/flowable-custom-engine-configuration\">GitHub<\/a> repository.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will go into detail on how to customize Flowable&#8217;s engine. Three changes to the engine will be done: (1) Change the database connection by modifying the data source and adding custom data source properties. (2)Use a strong UUID generator. (3)Implement a custom event handler.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[31,30,61,47,3,65],"tags":[18,34,10,67],"class_list":["post-471","post","type-post","status-publish","format-standard","hentry","category-bpm","category-flowable","category-flowable-bpm","category-open-source","category-spring","category-spring-boot","tag-bpm","tag-flowable","tag-open-source","tag-spring-boot"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p8EwXo-7B","jetpack-related-posts":[{"id":477,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/27\/use-flowable-apps-with-a-custom-rest-api\/","url_meta":{"origin":471,"position":0},"title":"Use Flowable Apps with a Custom REST API","author":"canchitodev","date":"June 27, 2020","format":false,"excerpt":"In this post, you will learn how configure Flowable's apps to use your custom Spring Boot REST API as a backend engine. All this, in a dockerized environment.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Tomcat Main","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=700%2C400 2x"},"classes":[]},{"id":356,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2019\/07\/05\/run-flowable-bpm-using-docker-and-mysql\/","url_meta":{"origin":471,"position":1},"title":"Run Flowable BPM using Docker and MySQL","author":"canchitodev","date":"July 5, 2019","format":false,"excerpt":"In this article, you will learn how to compile Flowable source code using MySQL as database source, and generate valid Docker images. Once you have the images, we will use Docker Compose for defining and running a multi-container Docker applications.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":184,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2018\/03\/30\/asynchronous-service-invocation-using-flowable\/","url_meta":{"origin":471,"position":2},"title":"Asynchronous Service Invocation using Flowable","author":"canchitodev","date":"March 30, 2018","format":false,"excerpt":"In this article, I will explain one possible method to solved some \"limitations\" encountered during the integration and implementation of\u00a0Flowable BPM, when executing long-running tasks, by implementing the Signallable Flowable Behavior and a database table as a task queue. Similar behavior can be achieved using Flowable's send task and receive\u2026","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Task Queue Service","src":"https:\/\/i0.wp.com\/canchito-dev.com\/img\/cwm\/userguide\/canchito_dev_task_queue_service.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":370,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/05\/12\/integrate-flowable-into-your-spring-boot-application\/","url_meta":{"origin":471,"position":3},"title":"Integrate Flowable into your Spring Boot Application","author":"canchitodev","date":"May 12, 2020","format":false,"excerpt":"In\u00a0this\u00a0tutorial,\u00a0we\u00a0will\u00a0be\u00a0integrating\u00a0Flowable's\u00a0BPM\u00a0engine\u00a0into\u00a0our\u00a0Spring\u00a0Boot\u00a0application.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Spring Initializr","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr-1024x674.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr-1024x674.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr-1024x674.png?resize=525%2C300 1.5x"},"classes":[]},{"id":372,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/07\/create-custom-service-tasks-for-flowable\/","url_meta":{"origin":471,"position":4},"title":"Create Custom Service Tasks for Flowable","author":"canchitodev","date":"June 7, 2020","format":false,"excerpt":"In\u00a0this\u00a0tutorial,\u00a0we\u00a0will\u00a0be\u00a0implementing\u00a0a\u00a0custom\u00a0service\u00a0task\u00a0in\u00a0Flowable\u00a0","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Spring Initializr","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=1050%2C600 3x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=1400%2C800 4x"},"classes":[]},{"id":458,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/05\/14\/deploying-flowable-in-a-docker-container-and-mysql-part-2\/","url_meta":{"origin":471,"position":5},"title":"Deploying Flowable in a Docker Container and MySQL (Part 2)","author":"canchitodev","date":"May 14, 2020","format":false,"excerpt":"This is the second part of our \"Deploying Flowable in a Docker Container and MySQL\" series. In this post, you will learn how to deploy Flowable's war files in a container running Tomcat, and connecting to another container running use MySQL database.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Tomcat Main","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=700%2C400 2x"},"classes":[]}],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/471","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/comments?post=471"}],"version-history":[{"count":5,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/471\/revisions"}],"predecessor-version":[{"id":532,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/471\/revisions\/532"}],"wp:attachment":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/media?parent=471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/categories?post=471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/tags?post=471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}