Chapter 5. Managing workflow persistence You can configure a SonataFlow instance to use persistence and store workflow context in a relational database. By design, Kubernetes pods are stateless. This behavior can pose challenges for workloads that need to maintain the application state across pod restarts. In the case of OpenShift Serverless Logic, the workflow context is lost when the pod restarts by default. To ensure workflow recovery in such scenarios, you must configure workflow runtime persistence. Use the SonataFlowPlatform custom resource (CR) or the SonataFlow CR to provide this configuration. The scope of the configuration varies depending on which resource you use. 5.1. Configuring persistence using the SonataFlowPlatform CR The SonataFlowPlatform custom resource (CR) enables persistence configuration at the namespace level. This approach applies the persistence settings automatically to all workflows deployed in the namespace. It simplifies resource configuration, especially when multiple workflows in the namespace belong to the same application. While this configuration is applied by default, individual workflows in the namespace can override it using the SonataFlow CR. The OpenShift Serverless Logic Operator also uses this configuration to set up persistence for supporting services. Note The persistence configurations are applied only at the time of workflow deployment. Changes to the SonataFlowPlatform CR do not affect workflows that are already deployed. Procedure Define the SonataFlowPlatform CR. Specify the persistence settings in the persistence field under the SonataFlowPlatform CR spec. apiVersion: sonataflow.org/v1alpha08 kind: SonataFlowPlatform metadata: name: sonataflow-platform-example namespace: example-namespace spec: persistence: postgresql: serviceRef: name: postgres-example 1 namespace: postgres-example-namespace 2 databaseName: example-database 3 port: 1234 4 secretRef: name: postgres-secrets-example 5 userKey: POSTGRESQL_USER 6 passwordKey: POSTGRESQL_PASSWORD 7 1 Name of the Kubernetes Service connecting to the PostgreSQL database. 2 Optional: Namespace of the PostgreSQL Service. Defaults to the namespace of the SonataFlowPlatform . 3 Name of the PostgreSQL database for storing workflow data. 4 Optional: Port number to connect to the PostgreSQL service. Defaults to 5432 . 5 Name of the Kubernetes Secret containing database credentials. 6 Key in the Secret object that contains the database username. 7 Key in the Secret object that contains the database password. View the generated environment variables for the workflow. The following example shows the generated environment variables for a workflow named example-workflow deployed with the earlier SonataFlowPlatform configuration. These configurations specifically relate to persistence and are managed by the OpenShift Serverless Logic Operator. You cannot modify these settings once you have applied them. Note When you use the SonataFlowPlatform persistence, every workflow is configured to use a PostgreSQL schema name equal to the workflow name. env: - name: QUARKUS_DATASOURCE_USERNAME valueFrom: secretKeyRef: name: postgres-secrets-example key: POSTGRESQL_USER - name: QUARKUS_DATASOURCE_PASSWORD valueFrom: secretKeyRef: name: postgres-secrets-example key: POSTGRESQL_PASSWORD - name: QUARKUS_DATASOURCE_DB_KIND value: postgresql - name: QUARKUS_DATASOURCE_JDBC_URL value: >- jdbc:postgresql://postgres-example.postgres-example-namespace:1234/example-database?currentSchema=example-workflow - name: KOGITO_PERSISTENCE_TYPE value: jdbc When this persistence configuration is in place, the OpenShift Serverless Logic Operator configures every workflow deployed in this namespace using the preview or gitops profile, to connect with the PostgreSQL database by injecting relevant JDBC connection parameters as environment variables. Note PostgreSQL is currently the only supported database for persistence. For SonataFlow CR deployments using the preview profile, the OpenShift Serverless Logic build system automatically includes specific Quarkus extensions required for enabling persistence. This ensures compatibility with persistence mechanisms, streamlining the workflow deployment process. 5.2. Configuring persistence using the SonataFlow CR The SonataFlow custom resource (CR) enables workflow-specific persistence configuration. You can use this configuration independently, even if SonataFlowPlatform persistence is already set up in the current namespace. Procedure Configure persistence by using the persistence field in the SonataFlow CR specification as shown in the following example: apiVersion: sonataflow.org/v1alpha08 kind: SonataFlow metadata: name: example-workflow annotations: sonataflow.org/description: Example Workflow sonataflow.org/version: 0.0.1 spec: persistence: postgresql: serviceRef: name: postgres-example 1 namespace: postgres-example-namespace 2 databaseName: example-database 3 databaseSchema: example-schema 4 port: 1234 5 secretRef: name: postgres-secrets-example 6 userKey: POSTGRESQL_USER 7 passwordKey: POSTGRESQL_PASSWORD 8 flow: 1 Name of the Kubernetes Service that connects to the PostgreSQL database server. 2 Optional: Namespace containing the PostgreSQL Service. Defaults to the workflow namespace. 3 Name of the PostgreSQL database where workflow data is stored. 4 Optional: Name of the database schema for workflow data. Defaults to the workflow name. 5 Optional: Port to connect to the PostgreSQL Service. Defaults to 5432 . 6 Name of the Kubernetes Secret containing database credentials. 7 Key in the Secret object containing the database username. 8 Key in the Secret object containing the database password. This configuration informs the OpenShift Serverless Logic Operator that the workflow must connect to the specified PostgreSQL database server when deployed. The OpenShift Serverless Logic Operator adds the relevant JDBC connection parameters as environment variables to the workflow container. Note PostgreSQL is currently the only supported database for persistence. For SonataFlow CR deployments using the preview profile, the OpenShift Serverless Logic build system includes the required Quarkus extensions to enable persistence automatically. 5.3. Persistence configuration precedence rules You can use SonataFlow custom resource (CR) persistence independently or alongside SonataFlowPlatform CR persistence. If a SonataFlowPlatform CR persistence configuration exists in the current namespace, the following rules determine which persistence configuration applies: If the SonataFlow CR includes a persistence configuration, that configuration takes precedence and applies to the workflow. If the SonataFlow CR does not include a persistence configuration and the spec.persistence field is absent, the OpenShift Serverless Logic Operator uses the persistence configuration from the current SonataFlowPlatform if any. To disable persistence for the workflow, explicitly set spec.persistence: {} in the SonataFlow CR. This configuration ensures the workflow does not inherit persistence settings from the SonataFlowPlatform CR. 5.4. Profile specific persistence requirements The persistence configurations provided for both SonataFlowPlatform custom resource (CR) and SonataFlow CR apply equally to the preview and gitops profiles. However, you must avoid using these configurations with the dev profile, as this profile ignores them entirely. The primary difference between the preview and gitops profiles lies in the build process. When using the gitops profile, ensure that the following Quarkus extensions are included in the workflow image during the build process. groupId artifactId version io.quarkus quarkus-agroal 3.8.6.redhat-00004 io.quarkus quarkus-jdbc-postgresql 3.8.6.redhat-00004 org.kie kie-addons-quarkus-persistence-jdbc 9.102.0.redhat-00005 If you are using the registry.redhat.io/openshift-serverless-1/logic-swf-builder-rhel8:1.35.0 to generate your images, you can pass the following build argument to include these extensions: USD QUARKUS_EXTENSIONS=io.quarkus:quarkus-agroal:3.8.6.redhat-00004,io.quarkus:quarkus-jdbc-postgresql:3.8.6.redhat-00004,org.kie:kie-addons-quarkus-persistence-jdbc:9.102.0.redhat-00005 5.5. Database schema initialization When you are using SonataFlow with PostgreSQL persistence, you can initialize the database schema either by enabling Flyway or by manually applying database schema updates using Data Definition Language (DDL) scripts. Flyway is managed by the kie-addons-quarkus-flyway runtime module and it is disabled by default. To enable Flyway, you must configure it using one of the following methods: 5.5.1. Flyway configuration in the workflow ConfigMap To enable Flyway in the workflow ConfigMap , you can add the following property: Example of enabling Flyway in the workflow ConfigMap apiVersion: v1 kind: ConfigMap metadata: labels: app: example-workflow name: example-workflow-props data: application.properties: | kie.flyway.enabled = true 5.5.2. Flyway configuration using environment variables in the workflow container You can enable Flyway by adding an environment variable to the spec.podTemplate.container field in the SonataFlow CR by using the following example: Example of enabling Flyway by using the workflow container environment variable apiVersion: sonataflow.org/v1alpha08 kind: SonataFlow metadata: name: example-workflow annotations: sonataflow.org/description: Example Workflow sonataflow.org/version: 0.0.1 spec: podTemplate: container: env: - name: KIE_FLYWAY_ENABLED value: 'true' flow: ... 5.5.3. Flyway configuration using SonataFlowPlatform properties To apply a common Flyway configuration to all workflows within a namespace, you can add the property to the spec.properties.flow field of the SonataFlowPlatform CR shown in the following example: Note This configuration is applied during workflow deployment. Ensure the Flyway property is set before deploying workflows. Example of enabling Flyway by using the SonataFlowPlatform properties apiVersion: sonataflow.org/v1alpha08 kind: SonataFlowPlatform metadata: name: sonataflow-platform spec: properties: flow: - name: kie.flyway.enabled value: true 5.5.4. Initializing a manual database using DDL scripts If you prefer manual initialization, you must disable Flyway by ensuring the kie.flyway.enabled property is either not configured or explicitly set to false . By default, each workflow uses a schema name equal to the workflow name. Ensure that you manually apply the schema initialization for each workflow. If you are using the SonataFlow custom resource (CR) persistence configuration, you can specify a custom schema name. Procedure Download the DDL scripts from the kogito-ddl-9.102.0.redhat-00005-db-scripts.zip location. Extract the files. Run the .sql files located in the root directory on the target PostgreSQL database. Ensure that the files are executed in the order of their version numbers. For example: V1.35.0__create_runtime_PostgreSQL.sql V10.0.0__add_business_key_PostgreSQL.sql V10.0.1__alter_correlation_PostgreSQL.sql Note The file version numbers are not associated with the OpenShift Serverless Logic Operator versioning.

Commands:
apiVersion: sonataflow.org/v1alpha08 kind: SonataFlowPlatform metadata: name: sonataflow-platform-example namespace: example-namespace spec: persistence: postgresql: serviceRef: name: postgres-example 1 namespace: postgres-example-namespace 2 databaseName: example-database 3 port: 1234 4 secretRef: name: postgres-secrets-example 5 userKey: POSTGRESQL_USER 6 passwordKey: POSTGRESQL_PASSWORD 7
env: - name: QUARKUS_DATASOURCE_USERNAME valueFrom: secretKeyRef: name: postgres-secrets-example key: POSTGRESQL_USER - name: QUARKUS_DATASOURCE_PASSWORD valueFrom: secretKeyRef: name: postgres-secrets-example key: POSTGRESQL_PASSWORD - name: QUARKUS_DATASOURCE_DB_KIND value: postgresql - name: QUARKUS_DATASOURCE_JDBC_URL value: >- jdbc:postgresql://postgres-example.postgres-example-namespace:1234/example-database?currentSchema=example-workflow - name: KOGITO_PERSISTENCE_TYPE value: jdbc
apiVersion: sonataflow.org/v1alpha08 kind: SonataFlow metadata: name: example-workflow annotations: sonataflow.org/description: Example Workflow sonataflow.org/version: 0.0.1 spec: persistence: postgresql: serviceRef: name: postgres-example 1 namespace: postgres-example-namespace 2 databaseName: example-database 3 databaseSchema: example-schema 4 port: 1234 5 secretRef: name: postgres-secrets-example 6 userKey: POSTGRESQL_USER 7 passwordKey: POSTGRESQL_PASSWORD 8 flow:
QUARKUS_EXTENSIONS=io.quarkus:quarkus-agroal:3.8.6.redhat-00004,io.quarkus:quarkus-jdbc-postgresql:3.8.6.redhat-00004,org.kie:kie-addons-quarkus-persistence-jdbc:9.102.0.redhat-00005
apiVersion: v1 kind: ConfigMap metadata: labels: app: example-workflow name: example-workflow-props data: application.properties: | kie.flyway.enabled = true
apiVersion: sonataflow.org/v1alpha08 kind: SonataFlow metadata: name: example-workflow annotations: sonataflow.org/description: Example Workflow sonataflow.org/version: 0.0.1 spec: podTemplate: container: env: - name: KIE_FLYWAY_ENABLED value: 'true' flow:
apiVersion: sonataflow.org/v1alpha08 kind: SonataFlowPlatform metadata: name: sonataflow-platform spec: properties: flow: - name: kie.flyway.enabled value: true