Skip to content

Commit

Permalink
merge: #9972
Browse files Browse the repository at this point in the history
9972: fix: ignore unknown extension elements r=saig0 a=menski

## Description

Allow users to deploy BPMN models with unknown extension elements added by other vendors to allow round-trips and migrations.

## Related issues

closes #4817 



Co-authored-by: Sebastian Menski <sebastian.menski@camunda.com>
  • Loading branch information
zeebe-bors-camunda[bot] and menski committed Aug 4, 2022
2 parents 0e6c55d + c3aee33 commit 4bf028e
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 5 deletions.
5 changes: 5 additions & 0 deletions bpmn-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
<artifactId>camunda-xml-model</artifactId>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<!-- Test dependencies -->

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import java.util.LinkedList;
import org.camunda.bpm.model.xml.impl.util.ModelUtil;
import org.camunda.bpm.model.xml.instance.ModelElementInstance;
import org.camunda.bpm.model.xml.type.ModelElementType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Walks the elements of a {@link BpmnModelInstance} and invokes the provided {@link
Expand All @@ -44,6 +47,8 @@
*/
public class ModelWalker {

private static final Logger LOG = LoggerFactory.getLogger(ModelWalker.class);

private final BpmnModelInstanceImpl modelInstance;
private final Deque<BpmnModelElementInstance> elementsToVisit = new LinkedList<>();

Expand All @@ -62,12 +67,14 @@ public void walk(final ModelElementVisitor visitor) {
final Collection<ModelElementInstance> children = getChildElements(currentElement);
children.forEach(
c -> {
try {
if (c instanceof BpmnModelElementInstance) {
elementsToVisit.addFirst((BpmnModelElementInstance) c);
} catch (ClassCastException e) {
throw new RuntimeException(
"Unable to process unknown element with name " + c.getDomElement().getLocalName(),
e);
} else {
final ModelElementType elementType = c.getElementType();
LOG.debug(
"Ignoring unknown BPMN element '{}:{}'",
elementType.getTypeNamespace(),
elementType.getTypeName());
}
}); // depth-first
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,20 @@
import io.camunda.zeebe.model.bpmn.instance.Activity;
import io.camunda.zeebe.model.bpmn.instance.BaseElement;
import io.camunda.zeebe.model.bpmn.instance.BpmnModelElementInstance;
import io.camunda.zeebe.model.bpmn.instance.Definitions;
import io.camunda.zeebe.model.bpmn.instance.EndEvent;
import io.camunda.zeebe.model.bpmn.instance.ExclusiveGateway;
import io.camunda.zeebe.model.bpmn.instance.FlowElement;
import io.camunda.zeebe.model.bpmn.instance.FlowNode;
import io.camunda.zeebe.model.bpmn.instance.IntermediateCatchEvent;
import io.camunda.zeebe.model.bpmn.instance.ServiceTask;
import io.camunda.zeebe.model.bpmn.instance.StartEvent;
import io.camunda.zeebe.model.bpmn.instance.SubProcess;
import io.camunda.zeebe.model.bpmn.instance.Task;
import io.camunda.zeebe.model.bpmn.instance.TimerEventDefinition;
import io.camunda.zeebe.model.bpmn.instance.UserTask;
import io.camunda.zeebe.model.bpmn.instance.bpmndi.BpmnDiagram;
import io.camunda.zeebe.model.bpmn.instance.bpmndi.BpmnPlane;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -169,4 +178,31 @@ protected void visit(
Task.class,
UserTask.class);
}

@Test
public void shouldIgnoreUnknownElementsAndAttributes() {
// given
final BpmnModelInstance modelInstance =
Bpmn.readModelFromStream(ModelWalkerTest.class.getResourceAsStream("ModelWalkerTest.bpmn"));

final List<BpmnModelElementInstance> visitedElements = new ArrayList<>();

final ModelWalker walker = new ModelWalker(modelInstance);

// when
walker.walk(visitedElements::add);

// then

assertThat(visitedElements)
.anyMatch(Definitions.class::isInstance)
.anyMatch(StartEvent.class::isInstance)
.anyMatch(ExclusiveGateway.class::isInstance)
.anyMatch(ServiceTask.class::isInstance)
.anyMatch(IntermediateCatchEvent.class::isInstance)
.anyMatch(TimerEventDefinition.class::isInstance)
.anyMatch(EndEvent.class::isInstance)
.anyMatch(BpmnDiagram.class::isInstance)
.anyMatch(BpmnPlane.class::isInstance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:unknown="http://example.com/schema/unknown/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0qh9wc7" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.0.0" unknown:attribute="value">
<bpmn:process id="process" name="Process" isExecutable="true" unknown:attribute="value">
<bpmn:startEvent id="start" name="Start">
<bpmn:extensionElements>
<unknown:elements>
<unknown:element/>
<unknown:element/>
</unknown:elements>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_1ghqtxk</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:exclusiveGateway id="fork" default="Flow_0829k0f" unknown:attribute="value">
<bpmn:incoming>Flow_1ghqtxk</bpmn:incoming>
<bpmn:outgoing>Flow_0829k0f</bpmn:outgoing>
<bpmn:outgoing>Flow_1yxvdzm</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_1ghqtxk" sourceRef="start" targetRef="fork" />
<bpmn:sequenceFlow id="Flow_0829k0f" sourceRef="fork" targetRef="task" />
<bpmn:exclusiveGateway id="join">
<bpmn:incoming>Flow_1mj7vtb</bpmn:incoming>
<bpmn:incoming>Flow_1e9zid1</bpmn:incoming>
<bpmn:outgoing>Flow_0zeynk4</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_1mj7vtb" sourceRef="task" targetRef="join" />
<bpmn:endEvent id="end" name="End">
<bpmn:incoming>Flow_0zeynk4</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0zeynk4" sourceRef="join" targetRef="end" />
<bpmn:sequenceFlow id="Flow_1yxvdzm" sourceRef="fork" targetRef="timer">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">= day of week(today()) = "Tuesday"</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_1e9zid1" sourceRef="timer" targetRef="join"/>
<bpmn:serviceTask id="task" name="Task" unknown:attribute="value">
<bpmn:extensionElements>
<zeebe:taskDefinition type="task" unknown:attribute="value" />
<unknown:element/>
</bpmn:extensionElements>
<bpmn:incoming>Flow_0829k0f</bpmn:incoming>
<bpmn:outgoing>Flow_1mj7vtb</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:intermediateCatchEvent id="timer" name="Timer">
<bpmn:incoming>Flow_1yxvdzm</bpmn:incoming>
<bpmn:outgoing>Flow_1e9zid1</bpmn:outgoing>
<bpmn:timerEventDefinition id="TimerEventDefinition_17m8b78" unknown:attribute="value">
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression" unknown:attribute="value">PT15S</bpmn:timeDuration>
</bpmn:timerEventDefinition>
</bpmn:intermediateCatchEvent>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ZeebePropertiesTest" unknown:attribute="value">
<bpmndi:BPMNEdge id="Flow_1ghqtxk_di" bpmnElement="Flow_1ghqtxk">
<di:waypoint x="208" y="120" />
<di:waypoint x="265" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0829k0f_di" bpmnElement="Flow_0829k0f">
<di:waypoint x="315" y="120" />
<di:waypoint x="380" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1mj7vtb_di" bpmnElement="Flow_1mj7vtb">
<di:waypoint x="480" y="120" />
<di:waypoint x="545" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0zeynk4_di" bpmnElement="Flow_0zeynk4">
<di:waypoint x="595" y="120" />
<di:waypoint x="662" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1yxvdzm_di" bpmnElement="Flow_1yxvdzm">
<di:waypoint x="290" y="145" />
<di:waypoint x="290" y="230" />
<di:waypoint x="412" y="230" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1e9zid1_di" bpmnElement="Flow_1e9zid1">
<di:waypoint x="448" y="230" />
<di:waypoint x="570" y="230" />
<di:waypoint x="570" y="145" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0g93o5e_di" bpmnElement="start">
<dc:Bounds x="172" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="179" y="145" width="24" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0x3gaj1_di" bpmnElement="fork" isMarkerVisible="true">
<dc:Bounds x="265" y="95" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="282" y="155" width="17" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_01u8vik_di" bpmnElement="join" isMarkerVisible="true">
<dc:Bounds x="545" y="95" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1iiq4dg_di" bpmnElement="end">
<dc:Bounds x="662" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="670" y="145" width="20" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0nj48w2_di" bpmnElement="task">
<dc:Bounds x="380" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_11lmofq_di" bpmnElement="timer">
<dc:Bounds x="412" y="212" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="416" y="255" width="29" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
18 changes: 18 additions & 0 deletions bpmn-model/src/test/resources/log4j2-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">

<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>

<Loggers>
<Logger name="io.camunda.zeebe" level="debug"/>

<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>

</Configuration>

0 comments on commit 4bf028e

Please sign in to comment.