Workflow Example 2
Create Workflow Definition
Let's create a workflow that monitors specified folders and when a video file appears in some of them transcodes it with a selected transcoding template.
LAPIS emits BPMN signals related to an object's lifecycle. The workflow will monitor two specific signals using Signal Start Events:
-
objectCreated – Triggered when a new object is added to the system.
-
objectUpdated – Triggered when an existing object is modified.
When an object is created, the workflow will verify whether it is linked to one of the monitored folders. Similarly, when an existing object is modified, the workflow will check if it is linked to any of the monitored folders.
Let assume we have some folders:
For this example we will monitor "Folder 1" and "Folder 2". We will need their IDs which we can get by displaying the ID column:
We will also use a Transcoding Template holding the transcoding parameters, so get its ID, too:
Now let's create a new workflow definition as shown:
- Set general properties Name, ID and Executable:
- Important is to also add the following "Extension Property", so that workflow history is not flooded with all workflow instances that are created for any object creation or modification:
- Set the properties for the Object Created signal start event:
- Set the properties for the Object Updated signal start event:
- Set the following properties to the object-created Yes flow:
The script is:
Replace/add IDs of the folders you want to be monitored in the folders variable.def folders = [ '679d0faa3063823d2ba9a45c@1', // ID of "Folder 1" '679d0fb73063823d2ba9a45e@1', // ID of "Folder 2" ] def containers = (object.get('containers') ?: []).collect { it.id.toString() } def addedToAnyFolder = folders.intersect(containers) (object.unwrap().isInstanceOf('Video')) && !['draft', 'newObjectDraft'].contains(object.get('lifeCycleStatus')) && object.get('containers') != null && addedToAnyFolder
The object variable is defined for workflow instances that trigger either the objectCreated or objectUpdated signal events. By using
object.get()
, you can retrieve any property value from the object, including non-existent or undefined properties. If querying a property doesn't exist or has no value,get()
will returnnull
.Similarly, you can inspect and act upon other object properties as needed. For instance, in this example, the containers property contains IDs of folders (and/or other containers) that are linked to the current object.
The final script statement must evaluate to a Boolean value, which determines the outcome of the condition check. In this example, the script checks the following:
-
Whether the newly created object is of type 'Video'.
-
Whether the object is not in the process of being created (e.g., autosaves during data entry will have this state).
-
Whether the object is linked to one of the monitored folders (as required in this example).
-
- Set the following properties to the object-updated Yes flow:
The script is:
Match the folders variable to the previous script. (Note that there is way to set this variable ones in the workflow and use it on other places, but for simplicity we have put it in both scripts).def folders = [ '679d0faa3063823d2ba9a45c@1', // ID of "Folder 1" '679d0fb73063823d2ba9a45e@1', // ID of "Folder 2" ] def originalContainers = (originalObject.get('containers') ?: []).collect { it.id.toString() } def containers = (object.get('containers') ?: []).collect { it.id.toString() } def intersectOriginal = folders.intersect(originalContainers) ?: [] def intersectNew = folders.intersect(containers) ?: [] def addedToAnyFolder = intersectOriginal.size() == 0 && intersectNew.size() > 0 execution.hasVariable('originalObject') && (object.unwrap().isInstanceOf('Video')) && !['draft', 'newObjectDraft'].contains(object.get('lifeCycleStatus')) && addedToAnyFolder
- Set the following properties to the scripting task:
The script is:
def operationId = Context.operationHelpers.getOperationByName('TranscodeOperation', godUser).id def templateId = '679d218d3063823d2ba9a46d@1' // ID of the transcoding template Context.operations.executeOperationById(operationId, [object.id].toImmutableList(), helpers.getSubject(subject), [ templateId: helpers.relationFromString(templateId), ].toImmutableMap(), null)
Change the templateId variable with your own ID.
You can download the BPMN of the above example from here.
No Comments