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

feat(zeebe): add MigrateProcessInstance #97

Merged
merged 2 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading