Skip to content

Commit

Permalink
feat(zeebe): add MigrateProcessInstance (#97)
Browse files Browse the repository at this point in the history
* feat(zeebe): add MigrateProcessInstance

* test(zeebe): add test for migrateProcessInstance

fixes #49
  • Loading branch information
jwulf authored Apr 2, 2024
1 parent 6ae25eb commit 2a9a123
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 8 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/commitlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ jobs:

- name: Install dependencies
run: npm install
env:
GH_NPM_TOKEN: ${{ secrets.GH_NPM_TOKEN }}

- name: Lint last commit message
run: npx commitlint --from=${{ github.event.pull_request.base.sha }} --to=${{ github.event.pull_request.head.sha }} --verbose
Expand Down
91 changes: 91 additions & 0 deletions src/__tests__/testdata/MigrateProcess-Version-1.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1cfwunf" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.21.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.4.0">
<bpmn:process id="migrant-work" name="migrant-work" isExecutable="true">
<bpmn:startEvent id="StartEvent_1" name="Start MigrationTest Process">
<bpmn:outgoing>Flow_167nn02</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_167nn02" sourceRef="StartEvent_1" targetRef="Activity_1fbznct" />
<bpmn:endEvent id="Event_0zwmdqk" name="End">
<bpmn:incoming>Flow_1r250pk</bpmn:incoming>
</bpmn:endEvent>
<bpmn:serviceTask id="Activity_1fbznct" name="Migrant Worker Task 1">
<bpmn:extensionElements>
<zeebe:taskDefinition type="migrant-worker-task-1" />
<zeebe:taskHeaders>
<zeebe:header key="ProcessVersion" value="1" />
</zeebe:taskHeaders>
</bpmn:extensionElements>
<bpmn:incoming>Flow_167nn02</bpmn:incoming>
<bpmn:outgoing>Flow_04fsyv6</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="Flow_1r250pk" sourceRef="Activity_0wjb7yn" targetRef="Event_0zwmdqk" />
<bpmn:sequenceFlow id="Flow_04fsyv6" sourceRef="Activity_1fbznct" targetRef="Activity_050vmrm" />
<bpmn:serviceTask id="Activity_0wjb7yn" name="Migrant Worker Task 2">
<bpmn:extensionElements>
<zeebe:taskDefinition type="migrant-worker-task-2" />
<zeebe:taskHeaders>
<zeebe:header key="ProcessVersion" value="1" />
</zeebe:taskHeaders>
</bpmn:extensionElements>
<bpmn:incoming>Flow_1igeic8</bpmn:incoming>
<bpmn:outgoing>Flow_1r250pk</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="Flow_1igeic8" sourceRef="Activity_050vmrm" targetRef="Activity_0wjb7yn" />
<bpmn:serviceTask id="Activity_050vmrm" name="Migration Checkpoint">
<bpmn:extensionElements>
<zeebe:taskDefinition type="migration-checkpoint" />
</bpmn:extensionElements>
<bpmn:incoming>Flow_04fsyv6</bpmn:incoming>
<bpmn:outgoing>Flow_1igeic8</bpmn:outgoing>
</bpmn:serviceTask>
</bpmn:process>
<bpmn:message id="Message_2h617dg" name="MigrationFinished">
<bpmn:extensionElements>
<zeebe:subscription correlationKey="=messageCorrelationKey" />
</bpmn:extensionElements>
</bpmn:message>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="migrant-work">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="164" y="142" width="66" height="40" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1rj9fgz_di" bpmnElement="Activity_1fbznct">
<dc:Bounds x="330" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0uo9rxu_di" bpmnElement="Activity_0wjb7yn">
<dc:Bounds x="600" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0zwmdqk_di" bpmnElement="Event_0zwmdqk">
<dc:Bounds x="822" y="99" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="830" y="142" width="20" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1io10nl_di" bpmnElement="Activity_050vmrm">
<dc:Bounds x="460" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_167nn02_di" bpmnElement="Flow_167nn02">
<di:waypoint x="215" y="117" />
<di:waypoint x="330" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1r250pk_di" bpmnElement="Flow_1r250pk">
<di:waypoint x="700" y="117" />
<di:waypoint x="822" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_04fsyv6_di" bpmnElement="Flow_04fsyv6">
<di:waypoint x="430" y="117" />
<di:waypoint x="460" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1igeic8_di" bpmnElement="Flow_1igeic8">
<di:waypoint x="560" y="117" />
<di:waypoint x="600" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
91 changes: 91 additions & 0 deletions src/__tests__/testdata/MigrateProcess-Version-2.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1cfwunf" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.21.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.4.0">
<bpmn:process id="migrant-work" name="migrant-work" isExecutable="true">
<bpmn:startEvent id="StartEvent_1" name="Start MigrationTest Process">
<bpmn:outgoing>Flow_167nn02</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_167nn02" sourceRef="StartEvent_1" targetRef="Activity_1fbznct" />
<bpmn:endEvent id="Event_0zwmdqk" name="End">
<bpmn:incoming>Flow_1r250pk</bpmn:incoming>
</bpmn:endEvent>
<bpmn:serviceTask id="Activity_1fbznct" name="Migrant Worker Task 1">
<bpmn:extensionElements>
<zeebe:taskDefinition type="migrant-worker-task-1" />
<zeebe:taskHeaders>
<zeebe:header key="ProcessVersion" value="2" />
</zeebe:taskHeaders>
</bpmn:extensionElements>
<bpmn:incoming>Flow_167nn02</bpmn:incoming>
<bpmn:outgoing>Flow_04fsyv6</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="Flow_1r250pk" sourceRef="Activity_0wjb7yn" targetRef="Event_0zwmdqk" />
<bpmn:sequenceFlow id="Flow_04fsyv6" sourceRef="Activity_1fbznct" targetRef="Activity_050vmrm" />
<bpmn:serviceTask id="Activity_0wjb7yn" name="Migrant Worker Task 2">
<bpmn:extensionElements>
<zeebe:taskDefinition type="migrant-worker-task-2" />
<zeebe:taskHeaders>
<zeebe:header key="ProcessVersion" value="2" />
</zeebe:taskHeaders>
</bpmn:extensionElements>
<bpmn:incoming>Flow_1igeic8</bpmn:incoming>
<bpmn:outgoing>Flow_1r250pk</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="Flow_1igeic8" sourceRef="Activity_050vmrm" targetRef="Activity_0wjb7yn" />
<bpmn:serviceTask id="Activity_050vmrm" name="Migration Checkpoint">
<bpmn:extensionElements>
<zeebe:taskDefinition type="migration-checkpoint" />
</bpmn:extensionElements>
<bpmn:incoming>Flow_04fsyv6</bpmn:incoming>
<bpmn:outgoing>Flow_1igeic8</bpmn:outgoing>
</bpmn:serviceTask>
</bpmn:process>
<bpmn:message id="Message_2h617dg" name="MigrationFinished">
<bpmn:extensionElements>
<zeebe:subscription correlationKey="=messageCorrelationKey" />
</bpmn:extensionElements>
</bpmn:message>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="migrant-work">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="164" y="142" width="66" height="40" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1rj9fgz_di" bpmnElement="Activity_1fbznct">
<dc:Bounds x="330" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0uo9rxu_di" bpmnElement="Activity_0wjb7yn">
<dc:Bounds x="600" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0zwmdqk_di" bpmnElement="Event_0zwmdqk">
<dc:Bounds x="822" y="99" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="830" y="142" width="20" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1io10nl_di" bpmnElement="Activity_050vmrm">
<dc:Bounds x="460" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_167nn02_di" bpmnElement="Flow_167nn02">
<di:waypoint x="215" y="117" />
<di:waypoint x="330" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1r250pk_di" bpmnElement="Flow_1r250pk">
<di:waypoint x="700" y="117" />
<di:waypoint x="822" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_04fsyv6_di" bpmnElement="Flow_04fsyv6">
<di:waypoint x="430" y="117" />
<di:waypoint x="460" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1igeic8_di" bpmnElement="Flow_1igeic8">
<di:waypoint x="560" y="117" />
<di:waypoint x="600" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
112 changes: 112 additions & 0 deletions src/__tests__/zeebe/integration/Client-MigrateProcessInstance.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { restoreZeebeLogging, suppressZeebeLogging } from 'lib'
import { DeployResourceResponse, ProcessDeployment } from 'zeebe/types'

import { ZeebeGrpcClient } from '../../../zeebe/index'
import { cancelProcesses } from '../../../zeebe/lib/cancelProcesses'

suppressZeebeLogging()

let res: DeployResourceResponse<ProcessDeployment> | undefined
let res1: DeployResourceResponse<ProcessDeployment> | undefined

afterAll(async () => {
restoreZeebeLogging()
await cancelProcesses(
res?.deployments[0].process.processDefinitionKey as string
)
await cancelProcesses(
res1?.deployments[0].process.processDefinitionKey as string
)
})

const zbc = new ZeebeGrpcClient()

test('ZeebeGrpcClient can migrate a process instance', async () => {
expect(true).toBe(true)
// Deploy a process model

res = await zbc.deployResource({
processFilename: './src/__tests__/testdata/MigrateProcess-Version-1.bpmn',
})

// Create an instance of the process model

const processInstance = await zbc.createProcessInstance({
bpmnProcessId: 'migrant-work',
variables: {},
})

let instanceKey = ''
let processVersion = 0

await new Promise((res) => {
const w = zbc.createWorker({
taskType: 'migrant-worker-task-1',
taskHandler: async (job) => {
instanceKey = job.processInstanceKey
processVersion = job.customHeaders.ProcessVersion as number
return job.complete().then((outcome) => {
w.close()
res(null)
return outcome
})
},
})
})

expect(instanceKey).toBe(processInstance.processInstanceKey)
expect(processVersion).toBe('1')

// Deploy the updated process model
res1 = await zbc.deployResource({
processFilename: './src/__tests__/testdata/MigrateProcess-Version-2.bpmn',
})

// Migrate the process instance to the updated process model
await zbc.migrateProcessInstance({
processInstanceKey: processInstance.processInstanceKey,
migrationPlan: {
mappingInstructions: [
{
sourceElementId: 'Activity_050vmrm',
targetElementId: 'Activity_050vmrm',
},
],
targetProcessDefinitionKey:
res1?.deployments[0].process.processDefinitionKey,
},
})

// Complete the job in the process instance

await new Promise((res) => {
const w = zbc.createWorker({
taskType: 'migration-checkpoint',
taskHandler: async (job) => {
return job.complete().then((outcome) => {
w.close()
res(null)
return outcome
})
},
})
})

await new Promise((res) => {
const w = zbc.createWorker({
taskType: 'migrant-worker-task-2',
taskHandler: async (job) => {
instanceKey = job.processInstanceKey
processVersion = job.customHeaders.ProcessVersion as number
return job.complete().then((outcome) => {
w.close()
res(null)
return outcome
})
},
})
})

expect(instanceKey).toBe(processInstance.processInstanceKey)
expect(processVersion).toBe('2')
})
5 changes: 5 additions & 0 deletions src/zeebe/lib/interfaces-1.0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
EvaluateDecisionRequest,
EvaluateDecisionResponse,
FailJobRequest,
MigrateProcessInstanceRequest,
MigrateProcessInstanceResponse,
ModifyProcessInstanceRequest,
ModifyProcessInstanceResponse,
ProcessInstanceCreationStartInstruction,
Expand Down Expand Up @@ -420,6 +422,9 @@ export interface ZBGrpc extends GrpcClient {
cancelProcessInstanceSync(processInstanceKey: {
processInstanceKey: string | number
}): Promise<void>
migrateProcessInstanceSync(
request: MigrateProcessInstanceRequest
): Promise<MigrateProcessInstanceResponse>
modifyProcessInstanceSync(
request: ModifyProcessInstanceRequest
): Promise<ModifyProcessInstanceResponse>
Expand Down
Loading

0 comments on commit 2a9a123

Please sign in to comment.