How it works
A workflow is a tree of typed steps. You hand that tree to a
WorkflowExecutorService, which walks it against a WorkflowContext —
resolving variables and expressions as it goes — and returns a
WorkflowResult.
Definition Engine Result
┌──────────┐ ┌───────────────────────┐ ┌──────────────────┐
│WorkflowData│ │ WorkflowExecutorService │ │ WorkflowResult │
│ (steps) │─▶│ + WorkflowContext │─▶│ success/halt/ │
│ │ │ scoped vars · mini: │ │ error · result │
└──────────┘ └───────────────────────┘ └──────────────────┘
The pieces
-
WorkflowData— the definition: a named workflow holding an ordered list of steps. Build it in Java, deserialize it from JSON, or parse it from PlantUML. -
Steps — each step is a typed node:
Step Does AssignVariablesStepSet variables from literals or expressions IfStepBranch on a condition ForEachStepIterate a collection (sequential or parallel) BlockStepGroup steps; produces a result CallWorkflowStepInvoke another workflow CodeStepRun a script (BeanShell / JavaScript / Groovy / Jython) HttpCallStepMake an HTTP request JumpToStep,HaltStepJump to a step; pause/stop execution FormStepHalt that carries a semantic-ui form; the filled fields become the resume params ( mc-workflow-step-form) -
WorkflowContext— the execution state: scoped variables, the input parameters, and step results. Built per run by aWorkflowContextFactory. -
Expressions — string values support
${variable}substitution; conditions and assignments support scripting prefixes, with the built-inmini:(MiniScript) language always available. TheDefaultWorkflowContextFactorywires the resolvers. -
WorkflowResult— the outcome:isSuccess(),isHalted(),isError(), andgetResult()for the final value.
Scripting
CodeStep runs code in a pluggable language runtime. Each language ships as its
own module (mc-workflow-code-beanshell, -javascript, -groovy, -jython)
and registers itself via the SPI described below — add the dependency and the
language is available.
Auto-registration (SPI)
Modules extend the engine without any wiring code. The mechanism is a Java
ServiceLoader SPI built around one interface:
public interface WorkflowConfigurer {
void configure(WorkflowContextFactory factory);
}
A module that wants to contribute — a scripting language, the Jackson serializer, your own step type — ships:
-
a
WorkflowConfigurerimplementation whoseconfigure(...)registers its step types (factory.getStepInstanceFactory().register(...)) and/or expression resolvers, and -
a service file listing that class:
META-INF/services/ai.mindconnect.workflow.execution.WorkflowConfigurer
To apply every configurer on the classpath automatically, add the
mc-workflow-spi-lookup module and build the factory with
SpiWorkflowContextFactory.create():
import ai.mindconnect.workflow.spi.SpiWorkflowContextFactory;
// ServiceLoader finds every WorkflowConfigurer on the classpath and
// calls configure() on a fresh DefaultWorkflowContextFactory — no manual calls.
WorkflowContextFactory factory = SpiWorkflowContextFactory.create();
WorkflowExecutorService service = new WorkflowExecutorService(factory);
Adding a module to the classpath is all it takes; the SPI does the
configure(...) for you. These modules ship a configurer out of the box:
mc-workflow-code-{javascript,groovy,beanshell,jython},
mc-workflow-jackson and mc-workflow-step-form.
Need extra setup on top of discovery? Take the factory create() returns and
modify it before building the executor:
WorkflowContextFactory factory = SpiWorkflowContextFactory.create();
factory.getStepInstanceFactory().register(MyData.class, MyStep::new);
WorkflowExecutorService service = new WorkflowExecutorService(factory);
(Without mc-workflow-spi-lookup you can still wire modules by hand —
new JavaScriptWorkflowConfigurer().configure(factory) — but the SPI is the
recommended path.)
Authoring options
- In Java — construct
WorkflowDataand step objects directly (see Getting started). - JSON —
mc-workflow-jackson(de)serializes definitions. - PlantUML —
mc-workflow-dsl-pumlparses a PlantUML activity diagram intoWorkflowData, so a diagram is the source.
Persistence
mc-workflow-persistence stores a WorkflowInstanceSnapshot (via the
WorkflowInstanceRepository port; a file-based implementation ships) so a
long-running workflow can pause (HaltStep) and later resume via
executorService.continueWorkflow(instance, params).