bpmn-io / bpmn-moddle

Read and write BPMN 2.0 XML from JavaScript.
MIT License
437 stars 162 forks source link

Zeebe support #64

Closed jessevanmuijden closed 4 years ago

jessevanmuijden commented 4 years ago

I want to load the following BPMN file created with Zeebe Modeler, edit the definitions with Javascript and then save it back to XML:

<?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:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_04qfpmy" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Zeebe Modeler" exporterVersion="0.6.2">
  <bpmn:process id="Process_0xqmjus" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>SequenceFlow_030hvxz</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_07uf7xh" name="input variable">
      <bpmn:incoming>SequenceFlow_030hvxz</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_14w2smw</bpmn:outgoing>
      <bpmn:messageEventDefinition messageRef="Message_0vynkyk" />
    </bpmn:intermediateCatchEvent>
    <bpmn:sequenceFlow id="SequenceFlow_030hvxz" sourceRef="StartEvent_1" targetRef="IntermediateCatchEvent_07uf7xh" />
    <bpmn:serviceTask id="ServiceTask_0hn4auw" name="DMN service worker">
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="DMN" />
        <zeebe:taskHeaders>
          <zeebe:header key="decisionRef" value="gemeente" />
        </zeebe:taskHeaders>
      </bpmn:extensionElements>
      <bpmn:incoming>SequenceFlow_14w2smw</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_0me26hk</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="SequenceFlow_14w2smw" sourceRef="IntermediateCatchEvent_07uf7xh" targetRef="ServiceTask_0hn4auw" />
    <bpmn:exclusiveGateway id="ExclusiveGateway_0lwoq16" default="SequenceFlow_0rxvizu">
      <bpmn:incoming>SequenceFlow_0me26hk</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_0bgq7ha</bpmn:outgoing>
      <bpmn:outgoing>SequenceFlow_0baxdyw</bpmn:outgoing>
      <bpmn:outgoing>SequenceFlow_0rxvizu</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:sequenceFlow id="SequenceFlow_0me26hk" sourceRef="ServiceTask_0hn4auw" targetRef="ExclusiveGateway_0lwoq16" />
    <bpmn:endEvent id="EndEvent_1dcsk6s" name="approval">
      <bpmn:incoming>SequenceFlow_0bgq7ha</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_0bgq7ha" sourceRef="ExclusiveGateway_0lwoq16" targetRef="EndEvent_1dcsk6s">
      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">toekenning == true</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:endEvent id="EndEvent_1occty5" name="rejection">
      <bpmn:incoming>SequenceFlow_0baxdyw</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_0baxdyw" sourceRef="ExclusiveGateway_0lwoq16" targetRef="EndEvent_1occty5">
      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">afwijzing == true</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:endEvent id="EndEvent_0uxxa9g">
      <bpmn:incoming>SequenceFlow_0rxvizu</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_0rxvizu" name="nothing" sourceRef="ExclusiveGateway_0lwoq16" targetRef="EndEvent_0uxxa9g" />
  </bpmn:process>
  <bpmn:message id="Message_0vynkyk" name="Message_14e2v28">
    <bpmn:extensionElements>
      <zeebe:subscription correlationKey="uuid" />
    </bpmn:extensionElements>
  </bpmn:message>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0xqmjus">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="242" y="81" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="IntermediateCatchEvent_07uf7xh_di" bpmnElement="IntermediateCatchEvent_07uf7xh">
        <dc:Bounds x="242" y="153" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="291" y="164" width="66" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_030hvxz_di" bpmnElement="SequenceFlow_030hvxz">
        <di:waypoint x="260" y="117" />
        <di:waypoint x="260" y="153" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="ServiceTask_0hn4auw_di" bpmnElement="ServiceTask_0hn4auw">
        <dc:Bounds x="210" y="229" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_14w2smw_di" bpmnElement="SequenceFlow_14w2smw">
        <di:waypoint x="260" y="189" />
        <di:waypoint x="260" y="229" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="ExclusiveGateway_0lwoq16_di" bpmnElement="ExclusiveGateway_0lwoq16" isMarkerVisible="true">
        <dc:Bounds x="235" y="341" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0me26hk_di" bpmnElement="SequenceFlow_0me26hk">
        <di:waypoint x="260" y="309" />
        <di:waypoint x="260" y="341" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="EndEvent_1dcsk6s_di" bpmnElement="EndEvent_1dcsk6s">
        <dc:Bounds x="335" y="348" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="333" y="391" width="43" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0bgq7ha_di" bpmnElement="SequenceFlow_0bgq7ha">
        <di:waypoint x="285" y="366" />
        <di:waypoint x="335" y="366" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="EndEvent_1occty5_di" bpmnElement="EndEvent_1occty5">
        <dc:Bounds x="156" y="348" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="154" y="391" width="42" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0baxdyw_di" bpmnElement="SequenceFlow_0baxdyw">
        <di:waypoint x="235" y="366" />
        <di:waypoint x="192" y="366" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="EndEvent_0uxxa9g_di" bpmnElement="EndEvent_0uxxa9g">
        <dc:Bounds x="242" y="443" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0rxvizu_di" bpmnElement="SequenceFlow_0rxvizu">
        <di:waypoint x="260" y="391" />
        <di:waypoint x="260" y="443" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="274" y="414" width="37" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

but I get the following error during moddle.toXml(definitions):

TypeError: Cannot read property 'isGeneric' of undefined
          at ElementSerializer.build (/projects/data/node_modules/moddle-xml/dist/index.js:1170:37)
          at Object.toXML (/projects/data/node_modules/moddle-xml/dist/index.js:1709:29)
          at BpmnModdle.toXML (/projects/data/node_modules/bpmn-moddle/dist/index.js:72:21)

I also tried with <bpmn2:definitions xmlns:bpmn2...``` fromREADME.md`, which resolves the error, but throws another error related to the ExtensionElement:

Error: unparsable content <zeebe:taskDefinition> detected
    line: 14
    column: 8
    nested error: missing namespace on <zeebe:taskDefinition>
    at error (/projects/data/node_modules/moddle-xml/dist/index.js:67:10)
    at handleError (/projects/data/node_modules/moddle-xml/dist/index.js:693:13)
    at handleError (/projects/data/node_modules/saxen/dist/index.js:196:5)
    at parse (/projects/data/node_modules/saxen/dist/index.js:981:20)
    at Parser.parse /projects/data/node_modules/saxen/dist/index.js:301:5)
    at Timeout._onTimeout (/projects/data/node_modules/moddle-xml/dist/index.js:860:14)

If someone with more knowledge of moddle could point out what needs to be changed or added to support BPMNs created with Zeebe Modeler, I would be happy to make a PR.

pinussilvestrus commented 4 years ago

Hi @jessevanmuijden ,

You will have to use the zeebe-bpmn-moddle which we use inside the ZeebeModeler alongside bpmn-moddle to handle Zeebe related diagrams.

var BpmnModdle = require('bpmn-moddle');

var zeebeModdle = require('./zeebe.json');

var moddle = new BpmnModdle({ zeebe: zeebeModdle });

/** do whatever you want **/

I'll close this since no actions seem to be needed. Please re-open if you follow-up in certain problems.

nikku commented 4 years ago

You could argue that a file inside the Zeebe Modeler is not the most ideal way to keep the Zeebe extensions around. Cf. https://github.com/camunda/camunda-bpmn-moddle.

pinussilvestrus commented 4 years ago

Makes totally sense, e.g. for creating plugins in the future. I just created an issue for that: https://github.com/zeebe-io/zeebe-modeler/issues/107