Dmn Integration
Zeebe integra un engine DMN basado en dmn-scala para evaluar decisiones de negocio directamente dentro del workflow engine, sin necesidad de un servicio externo. La evaluación usa FEEL (Friendly Enough Expression Language) como lenguaje de expresiones. El bridge entre BPMN y DMN es
BpmnDecisionBehavior, invocado por elBusinessRuleTaskProcessorcuando el elemento tiene uncalledDecisionId.
Arquitectura del DMN engine¶
El engine DMN vive en el módulo zeebe/dmn/ y actúa como wrapper sobre la biblioteca dmn-scala:
zeebe/dmn/
├── DmnScalaDecisionEngine ← Wrapper principal
├── ParsedDmnScalaDrg ← Resultado del parsing
├── FeelToMessagePackTransformer ← Conversión FEEL result → MessagePack
└── ... (support classes)
DmnScalaDecisionEngine¶
Clase principal que expone dos operaciones fundamentales:
parse(InputStream dmnResource) → ParsedDmnScalaDrg
Parsea un archivo DMN XML y produce un ParsedDmnScalaDrg (Decision Requirements Graph parseado). El parsing:
1. Lee el XML DMN 1.3 usando el parser de dmn-scala.
2. Valida la estructura (decision tables, input/output expressions, hit policies).
3. Pre-compila las expresiones FEEL de cada celda de la decision table.
4. Retorna un objeto inmutable listo para evaluación repetida.
El parsing ocurre una sola vez durante el deployment del recurso DMN. El ParsedDmnScalaDrg se almacena en el state store y se reutiliza para todas las evaluaciones.
evaluateDecisionById(ParsedDmnScalaDrg drg, String decisionId, Map<String, Object> variables) → DecisionEvaluationResult
Evalúa una decisión específica dentro del DRG:
1. Busca la decisión por decisionId dentro del DRG parseado.
2. Si la decisión depende de otras decisiones (DRG con dependencias), las evalúa recursivamente en orden topológico.
3. Para cada decision table: evalúa las input expressions contra las variables provistas, matchea las reglas, aplica la hit policy.
4. Retorna el resultado con todas las decisiones evaluadas en la cadena.
FEEL (Friendly Enough Expression Language)¶
El lenguaje de expresiones usado tanto en DMN como en los mappings y condiciones BPMN. Zeebe usa la implementación feel-scala que soporta FEEL 1.4+:
Características clave de FEEL:
- Tipado: number, string, boolean, date, time, duration, list, context, null.
- Expresiones: literales, aritmética, comparación, lógica, rangos ([1..10]), filtros (list[item > 5]).
- Funciones built-in: string manipulation, date/time, list operations, numeric functions.
- Contextos: {name: "foo", age: 30} — equivalente a objetos/maps.
- Invocación de funciones con named parameters.
En el contexto DMN: las input expressions, input entries, y output entries de una decision table son expresiones FEEL. El engine evalúa cada una contra las variables de input.
En el contexto BPMN: las condiciones de sequence flows, input/output mappings, y timer expressions también son FEEL.
Bridge BPMN-DMN: BpmnDecisionBehavior¶
BpmnDecisionBehavior es el behavior que conecta la ejecución BPMN con el engine DMN:
Flujo de evaluateDecision(context, element)¶
- Resolver decision ID: extrae el
calledDecisionIddel elemento BPMN (configurado en el XML del proceso). - Resolver binding: según el binding type, determina qué versión de la decisión DMN usar:
latest: la última versión deployada de la decisión.deployment: la versión que fue deployada junto con el proceso BPMN en el mismo deployment. Garantiza consistencia: el proceso siempre usa la decisión con la que fue deployado.versionTag: una versión específica identificada por tag semántico.- Obtener el DRG parseado: busca el
ParsedDmnScalaDrgen el state store por(decisionId, version). - Recopilar variables: obtiene las variables del scope actual del element instance para usarlas como input de la decisión.
- Evaluar: invoca
DmnScalaDecisionEngine.evaluateDecisionById()con el DRG, el decision ID, y las variables. - Convertir resultado: usa
FeelToMessagePackTransformerpara convertir el resultado FEEL a formato MessagePack (el formato binario de variables de Zeebe). - Escribir variables de resultado: el output de la decisión se escribe como variables en el scope del element instance.
- Emitir evento: escribe un record
DecisionEvaluationIntent.EVALUATEDoDecisionEvaluationIntent.FAILEDcon metadata completa de la evaluación.
FeelToMessagePackTransformer¶
Convierte tipos FEEL a MessagePack (el formato de serialización de variables de Zeebe):
| Tipo FEEL | Tipo MessagePack |
|---|---|
number |
Double o Long |
string |
String |
boolean |
Boolean |
date |
String (ISO 8601) |
time |
String (ISO 8601) |
duration |
String (ISO 8601) |
list |
Array |
context |
Map |
null |
Nil |
La conversión es necesaria porque dmn-scala usa tipos Java nativos, mientras que Zeebe almacena variables en MessagePack para eficiencia de espacio y velocidad de serialización/deserialización.
Binding types en detalle¶
latest (default)¶
- Usa la última versión deployada de la decisión DMN al momento de la evaluación.
- Riesgo: si se deploya una nueva versión de la decisión mientras una instancia de proceso está corriendo, instancias distintas del mismo proceso pueden evaluar versiones distintas de la decisión.
- Caso de uso: decisiones que deben actualizarse en caliente sin re-deployar el proceso.
deployment¶
- Usa la versión de la decisión DMN que fue deployada en el mismo
DeployResourcecall que el proceso BPMN. - Garantía: todas las instancias de una versión del proceso siempre evalúan la misma versión de la decisión.
- Restricción: la decisión DMN y el proceso BPMN deben deployarse juntos en la misma request.
- Caso de uso: consistencia estricta entre lógica de proceso y reglas de negocio.
versionTag¶
- Usa la versión de la decisión DMN identificada por un tag semántico (e.g.,
"v2.1"). - Flexibilidad: permite referenciar versiones específicas sin acoplarse al deployment.
- Caso de uso: procesos que necesitan pinear una versión específica de las reglas.
Evento DecisionEvaluation¶
Cada evaluación de decisión DMN genera un record en el log stream:
DecisionEvaluationIntent.EVALUATED¶
Indica una evaluación exitosa. Incluye:
- decisionKey, decisionId, decisionName, decisionVersion.
- decisionRequirementsId, decisionRequirementsKey (el DRG al que pertenece).
- output: resultado de la decisión.
- evaluatedDecisions: lista de todas las decisiones evaluadas en la cadena (si el DRG tiene dependencias). Cada una con sus input/output y reglas matcheadas.
- processInstanceKey, elementId: contexto BPMN donde se evaluó.
DecisionEvaluationIntent.FAILED¶
Indica un fallo en la evaluación. Incluye:
- Misma metadata que EVALUATED.
- failedDecisionId: qué decisión específica falló (puede ser una dependencia).
- failureMessage: descripción del error (input faltante, tipo inválido, expresión FEEL inválida, etc.).
Cuando la evaluación falla, BpmnDecisionBehavior crea un incidente en el element instance via BpmnIncidentBehavior, bloqueando la instancia hasta que un operador resuelva el problema (corrigiendo variables o re-deployando la decisión).