Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepared workflow is created incomplete #3754

Closed
matthias-ronge opened this issue Jun 10, 2020 · 14 comments · Fixed by #3811
Closed

Prepared workflow is created incomplete #3754

matthias-ronge opened this issue Jun 10, 2020 · 14 comments · Fixed by #3811
Labels

Comments

@matthias-ronge
Copy link
Collaborator

The workflow was created from the virtual machine that was prepared for the migration workshop. There are missing some transitions here. The missing transitions were drawn in by hand:

Anmerkung 2020-06-10 133723b

@Erikmitk
Copy link
Member

Can you upload the xml of the workflow? Would be interesting to see for #3755 and #3756 as well.

@matthias-ronge
Copy link
Collaborator Author

Workflow XML generated by migration tool
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:bpmn2="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:template="http://www.kitodo.org/template" id="sample-diagram"
                   targetNamespace="http://bpmn.io/schema/bpmn"
                   xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
    <bpmn2:process id="ChangeME" name="ChangeME" isExecutable="false"
                   template:outputName="ChangeME">
        <bpmn2:startEvent id="StartEvent_1">
            <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
        </bpmn2:startEvent>
        <bpmn2:task id="Task_1" name="Titelaufnahme" template:editType="4" template:processingStatus="1" template:concurrent="true" template:typeMetadata="false" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="false" template:typeImagesWrite="false" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_1" sourceRef="StartEvent_1" targetRef="Task_1"/>
        <bpmn2:task id="Task_2" name="Scannen" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="false" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="true" template:typeImagesWrite="true" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_2" sourceRef="Task_1" targetRef="Task_2"/>
        <bpmn2:task id="Task_3" name="TIFs einspielen" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="true" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="true" template:typeImagesWrite="true" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_4</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_3" sourceRef="Task_2" targetRef="Task_3"/>
        <bpmn2:task id="Task_4" name="Seitenkontrolle und-paginierung" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="true" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="true" template:typeImagesWrite="true" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_4" sourceRef="Task_3" targetRef="Task_4"/>
        <bpmn2:task id="Task_5" name="Struktur- und Metadatenerfassung" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="true" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="true" template:typeImagesWrite="true" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_5" sourceRef="Task_4" targetRef="Task_5"/>
        <bpmn2:task id="Task_6" name="Export Digitale Bibliothek" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="true" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="true" template:typeImagesWrite="true" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_6" sourceRef="Task_5" targetRef="Task_6"/>
        <bpmn2:task id="Task_8" name="PubPharm Datensatz" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="false" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="false" template:typeImagesWrite="false" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_8</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_9</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="Task_7" targetRef="Task_8"/>
        <bpmn2:task id="Task_9" name="Titelaufnahme O-Datensatz" template:editType="4" template:processingStatus="0" template:concurrent="true" template:typeMetadata="false" template:separateStructure="false" template:typeAutomatic="false" template:typeExportDMS="false" template:typeImagesRead="false" template:typeImagesWrite="false" template:typeAcceptClose="false" template:typeCloseVerify="false" template:batchStep="false" template:repeatOnCorrection="false" >
            <bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
            <bpmn2:outgoing>SequenceFlow_10</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="Task_8" targetRef="Task_9"/>
<bpmn2:endEvent id="EndEvent_1">
            <bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
        </bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="Task_8" targetRef="EndEvent_1"/>
    </bpmn2:process>
    <bpmndi:BPMNDiagram id="BPMNDiagram_1">
        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ChangeME">
            <bpmndi:BPMNShape id="_BPMNShape_StartEvent_1" bpmnElement="StartEvent_1">
                <dc:Bounds x="412" y="240" width="36" height="36"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_1_di" bpmnElement="SequenceFlow_1">
                <di:waypoint x="448" y="258"/>
                <di:waypoint x="498" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="473" y="237" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1">
                <dc:Bounds x="498" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_2_di" bpmnElement="SequenceFlow_2">
                <di:waypoint x="598" y="258"/>
                <di:waypoint x="648" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="623" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_2_di" bpmnElement="Task_2">
                <dc:Bounds x="648" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_3_di" bpmnElement="SequenceFlow_3">
                <di:waypoint x="748" y="258"/>
                <di:waypoint x="798" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="773" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_3_di" bpmnElement="Task_3">
                <dc:Bounds x="798" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_4_di" bpmnElement="SequenceFlow_4">
                <di:waypoint x="898" y="258"/>
                <di:waypoint x="948" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="923" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_4_di" bpmnElement="Task_4">
                <dc:Bounds x="948" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_5_di" bpmnElement="SequenceFlow_5">
                <di:waypoint x="1048" y="258"/>
                <di:waypoint x="1098" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="1073" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_5_di" bpmnElement="Task_5">
                <dc:Bounds x="1098" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_6_di" bpmnElement="SequenceFlow_6">
                <di:waypoint x="1198" y="258"/>
                <di:waypoint x="1248" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="1223" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_6_di" bpmnElement="Task_6">
                <dc:Bounds x="1248" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_7_di" bpmnElement="SequenceFlow_7">
                <di:waypoint x="1348" y="258"/>
                <di:waypoint x="1398" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="1373" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_8_di" bpmnElement="Task_8">
                <dc:Bounds x="1398" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_9_di" bpmnElement="SequenceFlow_9">
                <di:waypoint x="1498" y="258"/>
                <di:waypoint x="1548" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="1523" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Task_9_di" bpmnElement="Task_9">
                <dc:Bounds x="1548" y="218" width="100" height="80"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge id="SequenceFlow_10_di" bpmnElement="SequenceFlow_10">
                <di:waypoint x="1648" y="258"/>
                <di:waypoint x="1698" y="258"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="1673" y="247" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="EndEvent_1_di" bpmnElement="EndEvent_1">
                <dc:Bounds x="1698" y="240" width="36" height="36"/>
                <bpmndi:BPMNLabel>
                <dc:Bounds x="1716" y="280" width="0" height="12"/>
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNShape>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</bpmn2:definitions>

@Erikmitk
Copy link
Member

Erikmitk commented Jun 18, 2020

I opened the Workflow XML in the online BPMN.io Editor trial version (https://demo.bpmn.io) and got a bunch of error messages.

unparsable content <bpmn2:sequenceFlow> detected
	line: 56
	column: 0
	nested error: duplicate ID <SequenceFlow_9>

unresolved reference <SequenceFlow_7>

unresolved reference <Task_7>

unresolved reference <SequenceFlow_10>

unresolved reference <SequenceFlow_7>

unresolved reference <SequenceFlow_10>

no bpmnElement referenced in <bpmndi:BPMNEdge id="SequenceFlow_7_di" />

no bpmnElement referenced in <bpmndi:BPMNEdge id="SequenceFlow_10_di" />

The first issue seems to be a duplicate use of the same ID id="SequenceFlow_9". You can have either the first OR the last line here:

<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="Task_8" targetRef="Task_9"/>
        <bpmn2:endEvent id="EndEvent_1">
            <bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
        </bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="Task_8" targetRef="EndEvent_1"/>

The other issues mean that an element is referenced that does not exist or are incomplete. We go from <bpmn2:task id="Task_6" to <bpmn2:task id="Task_8" and there's no Task_7 though it gets referenced in a sequenceFlow <bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="Task_7" targetRef="Task_8"/>

I hope that helps. :)

@beatrycze-volk
Copy link
Collaborator

Was problem created by some external migration code or by Kitodo?

@matthias-ronge
Copy link
Collaborator Author

This is all in Kitodo. Precisely, here:

Migration

@Erikmitk
Copy link
Member

Erikmitk commented Jun 18, 2020

I see why the last sequence is a duplicate. There are two distinct methods to generate the IDs of the <bpmn2:sequenceFlows.

For Tasks the ordering attribute is used.

diagram.append(XmlGenerator.generateTask(task, "StartEvent_1", "Task_" + task.getOrdering()));

return generateTask(task, "Task_" + (task.getOrdering() - 1), "Task_" + task.getOrdering());

But for the endEvent the number of tasks is used.

Because these values are independent we end up with the same number by accident. Thereby creating a duplicate ID.

In the screenshot and the XML we can see that there are eight tasks. The SequenceFlow for the endEvent ends up with 8 + 1 = 9 as ID.

  1. Titelaufnahme
  2. Scannen
  3. TIFs einspielen
  4. Seitenkontrolle und-paginierung
  5. Struktur- und Metadatenerfassung
  6. Export Digitale Bibliothek
  7. PubPharm Datensatz
  8. Titelaufnahme O-Datensatz

But somehow we are missing Task_7 in the result which means that the ordering value of the last two must be wrong. Because of this the last Task also ends up with the SequenceFlow with the ID 9. That's how we got an invalid workflow XML representation.

I think it makes sense to sort the tasks by ordering to get them in the correct order. That's what this attribute is for, I guess.

My suggestion would be to not rely on this attribute to get the IDs though. Instead it's favorable to use a dumb old int i = 1; i++; approach to pass the correct task number to create the XML at this for-loop:

Apparently, the ordering attribute is not reliable so why not use an independent integer value that counts up. We are just iterating over a sorted task list one at a time. Why rely on a piece of information inside the tasks when we could simply count at which iteration of the for-loop we're at.

When the same value is also passed to generate the endEvent we will not run into the problem that these values ever diverge.

@Erikmitk
Copy link
Member

Erikmitk commented Jun 18, 2020

Can someone explain why there's a gap with the ordering attribute of the tasks?

Is it because the workflow was modified and Task 7 was removed at some point? The order of the tasks would be correct because the next one always has a higher number but now we have a gap in the values which had no relevance whatsoever in 2.x.

@beatrycze-volk
Copy link
Collaborator

beatrycze-volk commented Jun 18, 2020

Apparently, the ordering attribute is not reliable so why not use an independent integer value that counts up. We are just iterating over a sorted task list one at a time. Why rely on a piece of information inside the tasks when we could simply count at which iteration of the for-loop we're at.

Sounds like the good solution 😃

@matthias-ronge
Copy link
Collaborator Author

Can someone explain why there's a gap with the ordering attribute of the tasks?

Not yet. In the 2.x processes where this comes from, the number is even strictly ascending:

Steps

In database:

Database

Basically, the number does not have to be continuous. It can also be interrupted or a number appears more than once if two steps are parallel. This is completely legal in version 2 and it should work, too. But that's not even the case here.

@Erikmitk
Copy link
Member

Erikmitk commented Jun 19, 2020

Well… interesting where the gap comes from when the values are sequential but why that happens specifically for this example should not bother us further.

Basically, the number does not have to be continuous. It can also be interrupted or a number appears more than once if two steps are parallel.

That's all we need to know at this point. If it does not have to be continuous and there could be duplicates we cannot use the value to generate IDs the way it is implemented right now as I explained above.

For both cases we run into problems with duplicate IDs that make the initial migrated XML invalid from the start. Working with these ambiguous workflows in the editor keeps corrupting them further down the road.

@Erikmitk
Copy link
Member

Erikmitk commented Jun 19, 2020

Well… interesting where the gap comes from when the values are sequential but why that happens specifically for this example should not bother us further.

I should take that back!

🤔 Are we looking at the same workflow that was migrated? The tasks and their order do not match at all! What is happening? 👀

Migrated XML:

  1. Titelaufnahme
  2. Scannen
  3. TIFs einspielen
  4. Seitenkontrolle und-paginierung
  5. Struktur- und Metadatenerfassung
  6. Export Digitale Bibliothek
  7. PubPharm Datensatz
  8. Titelaufnahme O-Datensatz

image

The workflow has Tasks that are not in the database (PubPharm Datensatz and Titelaufnahme O-Datensatz). And the database has tasks that are not in the workflow (Begutachtung Bestandserhaltung and Remagazinierung). Also the order is not the same as e.g. Titelaufnahme is number 7 in the DB but the first one in the workflow.

Are we just looking at two independent workflows? Or is the migration broken?

@matthias-ronge
Copy link
Collaborator Author

Obviously I got the wrong tasks 🤦

@matthias-ronge
Copy link
Collaborator Author

matthias-ronge commented Jun 19, 2020

These are an example of the correct tasks (after migration):

Tasks in database

You see that there is no task number 7.

@Erikmitk
Copy link
Member

Phew… Crisis averted!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants