Repository navigation
Viewing workflows
Business applications often want to show a workflow. That means the BPMN diagram of the process and,
coloured on top of it, what already happened in that concrete workflow. VanillaBP provides everything a
BPMN viewer such as bpmn.io needs. It does so for every BPMS (business process
management system), through the same three methods of ProcessService:
List<ProcessDefinition> getProcessDefinitions(A workflowAggregate, String historyContext);
InputStream getBpmnXml(String processDefinitionId);
WorkflowHistory getWorkflowHistory(A workflowAggregate, String historyContext);The methods only read. Nothing is persisted, no transaction is required and the workflow does not move
on. The record types ProcessDefinition, WorkflowHistory and WorkflowElementHistory are documented
in the SPI's README.
-
The three parts
What each of the three methods returns, and in which order a viewer calls them. -
Digging into call activities
How a viewer goes down into a called process, level by level. -
Process definition ids are opaque
Why the id has to travel back unchanged, and what VanillaBP put into it. -
Ended workflows
How long a finished workflow can still be shown. -
Right after the start
Why a viewer opened seconds after the start still sees the workflow on an eventually consistent BPMS. -
Errors
The two exceptions and what each of them means. -
BPMS specifics
Which data a BPMS can serve, and where the gaps are written down.
-
getProcessDefinitions(aggregate, null)returns the definition the workflow runs on. ItsusedByElementsisnull. It also returns the definitions its call activities would call next, and each of them names the call-activity elements which use it. So a simple process without call activities returns exactly one entry. -
getBpmnXml(processDefinitionId)returns the BPMN XML of one of those definitions. Give it to the viewer. -
getWorkflowHistory(aggregate, null)returns when the workflow started and when it ended, if it did. It also returns the history of its elements in execution order. For each element this is the element id, the start and end time, whether it was canceled, and an error message if the element is in error right now. Use the element ids to colour the diagram.
Once a call activity was executed, its WorkflowElementHistory has a secondaryWorkflowHistoryContext.
Pass that value back as the historyContext argument to look at the called workflow. Then
getProcessDefinitions returns the definition which that instance actually runs on, plus ITS call
activities. And getWorkflowHistory returns its element history. This way a viewer lets users go down
the tree of processes level by level.
Never parse, build or shorten a ProcessDefinition#id(), and the same for the processDefinitionId
inside a WorkflowHistory. VanillaBP puts the adapter id which can resolve it in front of the BPMS'
own id. The reason: a workflow may run in any of the configured BPMS, and
getBpmnXml has no workflow aggregate to find the BPMS from. Pass the id back unchanged. A viewer may
of course carry it in a URL.
Viewing is not limited to running workflows. As long as the BPMS still holds the workflow's data, you
get definitions and history for ended workflows too. Most viewers show exactly these. Once the BPMS has
cleaned the data up (history retention), a WorkflowNotFoundException says so and tells you what to
do.
Some BPMS answer from a read model which is only eventually consistent. Camunda 8, for example,
searches its query API, and an exporter fills that API. Such a BPMS reports a workflow created moments
ago as unknown, although it is running. A viewer opened right after the start is exactly this case, so
a read waits. VanillaBP often knows which BPMS holds the workflow, because it started it there or got
a delivery of it. It reads this from the row it wrote when the workflow started, which is in your
database. So a second node and a node after a restart know it too. Then it asks that BPMS again until
the workflow shows up or the BPMS' own window has passed. For Camunda 8 this is
workflow-visibility-timeout,
10 seconds by default. In normal operation the wait is one to three seconds, and your call returns the
history it asked for.
VanillaBP does not wait for a workflow which nobody recorded. A wrong id fails at once, as it should.
If the window passes without an answer, the WorkflowNotFoundException names the BPMS which was
expected to hold the workflow. An exporter which has stopped looks exactly like one which is a moment
behind, so you need that name.
-
WorkflowNotFoundException: no configured BPMS knows the workflow. It was never started, or started elsewhere, or its history was cleaned up, or an expected BPMS stayed silent for the whole window above. -
ProcessDefinitionNotFoundException: the given definition id is malformed, or belongs to an adapter which is not configured (any more), or names a definition the BPMS does not hold any more.
Which data a BPMS can serve differs. Some record every flow node, some only activities, some no element history at all. A remote BPMS may also lag behind (eventual consistency) or need additional infrastructure. If an adapter serves less than the API offers, its Deviations page says so:
- Camunda 7: Learn more...
- Camunda 8: Learn more...
- bpm-crafters Process-Engine-API: Learn more...
