Back-end migration

Dependency changes

Published libraries

These are the changes that were made to the Valtimo libraries that get published:

Module
Change

besluit

Removed. Use besluiten-api instead.

connector

Removed. Use plugins instead.

contactmoment

Removed.

document

Merged into case. Packages are the same.

external-event

Removed. Partially replaced by portaaltaak, specifically for tasks.

form-flow-valtimo

Merged into form-flow. Packages are the same.

haalcentraal

Removed.

haalcentraal-brp

Removed.

klant

Removed.

objects-api

Removed. Use other ZGW modules instead.

openzaak

Removed. Use other ZGW modules instead.

openzaak-resource

Removed. Use other ZGW modules instead.

Used libraries

Library
Previous version
Current version

Camunda

7.21.0

Replaced with Operaton equivalent of 7.23.0.

com.mysql:mysql-connector-j

8.4.0

9.2.0

org.liquibase:liquibase-core org.liquibase.ext:liquibase-hibernate6

4.29.2

4.31.1

org.keycloak:keycloak-admin-client org.keycloak:keycloak-server-spi-private

24.0.5

26.0.5

org.postgresql:postgresql

42.7.4

42.7.5

org.springframework.boot

3.2.5

3.4.5

Case definitions

With the introduction of case definitions, the structure inside your resources folder will change. Additionally, some configuration files have new extensions, to further differentiate between what is configured. The tables below show what changes are made for Valtimo and ZGW resources.

Resource type
Old location
New location
Notes

BPMN

/**/bpmn/*.bpmn

/config/case/*/*/bpmn/*.bpmn

-

Case definition

-

/config/case/*/*/case/definition/*.case-definition.json

Replaces case settings. Click here for details.

Case list column

/config/case/list/*.json

/config/case/*/*/case/list/*.case-list.json

-

Case search field

/config/search/*.json

/config/case/*/*/case/search-field/*.schema.case-search-field.json

-

Case settings

/config/case/definition/*.json

-

Replaced by case definition.

Case tab

/config/case-tabs/*.case-tabs.json

/config/case/*/*/case/tab/*.case-tab.json

Structure changed, see below.

Case tag

/config/case-tag/*.json

/config/case/*/*/case/tag/*.case-tag.json

Structure changed, see below.

Case task list

/config/case-task-list/*.case-task-list.json

/config/case/*/*/case/task-list/*.case-task-list.json

Structure changed, see below.

Case widget tab

/config/case-widget-tab/*.case-widget-tab.json

/config/case/*/*/case/widget-tab/*.case-widget-tab.json

Structure changed, see below.

DMN

/**/dmn/*.dmn

/config/case/*/*/dmn/*.dmn

-

Document

resource/config/document/definition/*.schema.json

/config/case/*/*/document/definition/*.schema.document-definition.json

-

Form

/config/form/*.json

/config/case/*/*/form/*.form.json

-

Form flow

/config/form-flow/*.form-flow.json

/config/case/*/*/form-flow/*.form-flow.json

-

Global BPMN

/**/bpmn/*.bpmn

/config/global/bpmn/*.bpmn

-

Global DMN

/**/dmn/*.dmn

/config/global/dmn/*.dmn

-

Internal case status

/config/internal-case-status/*.internal-case-status.json

/config/case/*/*/case/internal-status/*.internal-case-status.json

Structure changed, see below.

Process document link

/config/process-document-link/*.json

/config/case/*/*/process-document-link/*.process-document-link.json

-

Process link

/config/processlink/*.processlink.json

/config/case/*/*/process-link/*.process-link.json

-

Task search field

/config/task-search-fields/*.task-search-field.json

/config/case/*/*/task-search-field/*.task-search-field.json

Structure changed, see below.

Migrating contents to their new structure

Some resources have also either had their structure change, as can be seen in the Contents updated column in the table above. With the introduction of versioning for case definitions, case related configuration files no longer have to depend on changesets. Additionally, each case definition should have its own configuration files. These changesets always followed the following pattern:

{
    "changesetId": "...",
    "case-definitions": [
        {
            "key": "...",
            "...": [
                <the actual configuration>
            ]
        }
    ]
}

These can now be simplified to the following pattern:

[
    <the actual configuration>
]

New resources

Case definitions adhere to the following structure:

{
    "key": "...",
    "name": "...",
    "versionTag": "1.0.0",
    "final": true,
    "canHaveAssignee": true,
    "autoAssignTasks": true
}
  • key. The key is the key of your case definition.

  • name. The name is the name of your case definition.

  • versionTag. Version tag in combination with case definition key has to be unique, and as long as a case definition is not yet final it can still be edited, and configurations can be updated as well. The version tag follows semantic versioning, so 1.0.0-something.

  • canHaveAssignee. Determines if users can be assigned to a case.

  • autoAssignTasks. Automatically assigns user tasks to the user assigned to the case. This can only be set to true if canHaveAssignee is enabled as well.

Case definition permissions

Case definition is a newly introduced resource. Some existing functionality now checks for this permission, such as the list of cases that can be selected in the left panel. Below is the list of resource and action type combinations that have been added, as well as when to use them/when they are used. Do not forget to configure these permissions for your Valtimo implementation.

Resource
Action
When to use

com.ritense.case_.domain.definition.CaseDefinition

view

  • When retrieving which case definition columns to show.

  • When retrieving an individual case definition.

  • When retrieving the available case tags for a case definition.

  • When retrieving the available internal case statuses for a case definition.

com.ritense.case_.domain.definition.CaseDefinition

view_list

  • When retrieving a list of case definitions, e.g. the list of cases in the left panel in the UI. This does not include related content, such as document details.

ZGW Object management permissions

Access to objects in the Objecten API is now granted via permissions. Below is the list of resource and action type combinations, as well as when they are used. Do not forget to configure these permissions for your Valtimo implementation.

Resource
Action
When to use

com.ritense.objectenapi.security.object

create

  • When creating an object via the Objecten API.

com.ritense.objectenapi.security.object

delete

  • When deleting an object via the Objecten API.

com.ritense.objectenapi.security.object

modify

  • When editing an object via the Objecten API.

com.ritense.objectenapi.security.object

view

  • When viewing a single object via the Objecten API.

com.ritense.objectenapi.security.object

view_list

  • When retrieving a list of objects, e.g. a list of objects for an object type.

Operaton

With Camunda 7 going end of life, Valtimo now uses Operaton as its process engine.The effort involved in the migration to Operaton depends on the level of Camunda integration in the implementation project. Operaton works on the same database structure Camunda uses, so no further migration is needed. If Camunda is used or referenced in your custom code, this will likely require changes.

UI only:

  • No changes are required

Config deployed on startup:

  • Permissions need to be updated

  • Camunda properties in the application configuration

Custom code:

  • Direct references to Camunda should be replaced in for example:

    • Valtimo class names

    • imports of Camunda classes

Infrastructure:

  • Camunda webapps configuration needs to be changed.

Permission changes

Some resources that permissions apply to have been renamed. Anything referencing Camunda in your permission configuration needs to be changed. This only applies to the configuration files loaded on startup. Any permissions in the database, like those previously imported or configured through the UI should be automatically migrated. These change apply to main resource type of the Permission and any resources used on container type conditions.

Before
After
{
    "resourceType": "com.ritense.valtimo.camunda.domain.CamundaTask",
    "action": "view",
    "roleKey": "ROLE_USER",
    "conditions": [
        {
            "type": "container",
            "resourceType": "com.ritense.valtimo.camunda.domain.CamundaIdentityLink",
            "conditions": [
                {
                    "type": "field",
                    "field": "groupId",
                    "operator": "==",
                    "value": "ROLE_USER"
                }
            ]
        }
    ]
},
{
    "resourceType": "com.ritense.valtimo.operaton.domain.OperatonTask",
    "action": "view",
    "roleKey": "ROLE_USER",
    "conditions": [
        {
            "type": "container",
            "resourceType": "com.ritense.valtimo.operaton.domain.OperatonIdentityLink",
            "conditions": [
                {
                    "type": "field",
                    "field": "groupId",
                    "operator": "==",
                    "value": "ROLE_USER"
                }
            ]
        }
    ]
},

The following resources have been renamed, note that this is both the package and the class name:

Old resource type name
New resource type name

com.ritense.valtimo.camunda.domain.CamundaTask

com.ritense.valtimo.operaton.domain.OperatonTask

com.ritense.valtimo.camunda.domain.CamundaExecution

com.ritense.valtimo.operaton.domain.OperatonExecution

com.ritense.valtimo.camunda.domain.CamundaIdentityLink

com.ritense.valtimo.operaton.domain.OperatonIdentityLink

com.ritense.valtimo.camunda.domain.CamundaProcessDefinition

com.ritense.valtimo.operaton.domain.OperatonProcessDefinition

Other changes in the codebase

Other changes required are impossible to list because they depend on how Camunda is used on the Valtimo project. These changes are generally simple and involve renaming Camunda to Operaton. Below are a number of examples of typical changes that need to be made.

Application configuration

References to Camunda properties in the application configuration should be changed. Usually this is done in applcation.yml

Before
After
spring:
    jersey:
        application-path: /api/camunda-rest
       
camunda:
    bpm:
        history-level: AUDIT
        history-level-default: AUDIT   
spring:
    jersey:
        application-path: /api/operaton-rest
       
operaton:
    bpm:
        history-level: AUDIT
        history-level-default: AUDIT   

Camunda packages

Camunda classes that are imported will have new package names. This is fixed by renaming org.camunda to org.operaton in imports.

Before
After
import org.camunda.bpm.engine.RuntimeService
import org.operaton.bpm.engine.RuntimeService

Class names

Both Camunda and Valtimo classes the have Camunda in the name have been changed. This is fixed by renaming Camunda to Operaton in the codebase.

Before
After
@Bean
fun myBean(
    taskService: CamundaTaskService
): MyBean {
    //...
}
@Bean
fun myBean(
    taskService: OperatonTaskService
): MyBean {
    //...
}

Camunda webapps

The Camunda webapps have been replaced by the Operaton equivalent. The url on which they are available has only been changed from https://host/camunda/app/ to https://host/operaton/app/ . This might required additional infrastructure changes to allow access to the correct path.

Minor migrations

Permission changes to user ID

A reference to a user is stored as part of a document (case handler), task (assignee) or note (creator). Because the option to pick what user identifier to use was removed, and username is used by default, this might have an impact on the configured permissions.

Lets say you have a permission where only the user who created a note for a case can delete that note. If Valtimo was set to use the user ID before, your permission might look like this.

{
    "resourceType": "com.ritense.note.domain.Note",
    "action": "delete",
    "conditions": [
        {
            "type": "field",
            "field": "createdByUserId",
            "operator": "==",
            "value": "${currentUserId}"
        }
    ]
}

Note the use of the ${currentUserId} expression. This will not match the username stored for the notes, resulting in users not being able to delete their notes. Instead this should be changed to ${currentUsername} , resulting in the following permission.

{
    "resourceType": "com.ritense.note.domain.Note",
    "action": "delete",
    "conditions": [
        {
            "type": "field",
            "field": "createdByUserId",
            "operator": "==",
            "value": "${currentUsername}"
        }
    ]
}

Document content

For security reasons, the document content has been removed from endpoints returning documents. For example GET /api/v1/document/{documentId} and POST /api/v1/document-definition/name/search. We recommend not exposing this information, as that can lead to users accessing case information that they should not have accesss to. Only the required information can be displayed using list columns, form-io, widget or summary tabs. If you still do want to return document content in these endpoints it is possible to turn this back on by enabling the following property.

valtimo:
    includeDocumentContentInResponse: true

Removed authorization toggles

The following deprecated toggles for authorization purposes were removed:

valtimo:
    authorization:
        objectenapi:
            enabled: true
        dashboard:
            enabled: true
        zgwDocuments:
            enabled: true

If your project made use of these toggles, these can now be removed. Additionally, permissions should be configured to allow access to these resources.

Database migration script

As with other versions of Valtimo, a migration script will automatically run on startup to apply the required database changes. For this version the changes are more extensive than usual because of the introduction of case definitions. After the migration the application should continue running existing cases as usual. For projects that use more custom code that might be impacted, some of the migration steps will be explained here so you can better judge if any additional steps are required.

It is strongly recommend making a database backup before deploying the new version.

Case definitions

Because of the introduction of case definitions, all cases should be linked to a case definition. This determines what configuration is used when working with this case. For example, which (version of) forms are used for user tasks, which tabs are displayed the detail page of that case or what supporting processes can be started. The migration script will set up a number of case definitions with the other configuration based on how the application would have behaved up until now.

The migration script does the following:

  • A case definition is created for every version of a document definition. The key of the case definition matches the old key of the document definition. The version of the case definition is also based on the version of the document definition and will always have the migrated suffix. For example, a document definition of version 7 will result in a case definition with version 0.7.0-migrated .

  • The document definition is linked to the newly created case definition.

  • Process definitions are copied to the new case definition. The processes that are copied are any process that were linked to the document definition. If other processes were started in a call activity, these process definitions are also copied. These copies are always based on the latest version of the process definition as this would also be the one that is started for major 12. Running processes are still linked to documents as they were before and will use the old process definition. Only newly started processes will use these new process definitions.

  • Copy and link the following configurations the new case definition:

    • Case tabs (including widgets).

    • Case tags.

    • Linked ZGW zaak types.

    • Forms. The forms that are copied are the ones used in:

      • Process links

      • Summary forms

      • FormIO tabs

      • FormIO widgets

      • Form flows

    • Form flows. The form flows that are copied are the ones used in process links.

    • Process links are copied together with the process definitions.

    • Decision definitions are copied to the new case definition if these decisions are used in any of the related process definitions.

Last updated