bpmnserver / bpmn-client Goto Github PK
View Code? Open in Web Editor NEWLightweight client for bpmn-server web-API
Lightweight client for bpmn-server web-API
Hi @ralphhanna,
This issue was not found in v1.3.28
.
Test Version: 1.4.1
(Double checked with a fresh installation of the new version)
There are some major issues with the execution of the boundary timers and their associated tasks.
I have a workflow like the below:
The services for ST1
& ST2
are DummyService1
& DummyService2
respectively. Both Wait1
& Wait2
have been set to PT2M
.
In my appDelegate.ts
, I have the services for both ST1
and ST2
.
async DummyService1(input, context) {
context.item.data.service1Result = 'Service1Exec';
}
async DummyService2(input, context) {
await delay(126000, '2.1mins'); // Wait for 2.1 mins
context.item.data.service2Result = 'Service2Exec';
}
I expect ST1
to be executed while ST2
won't be excuted as there is a delay of 2.1 mins before which the Wait2
will get triggered & the workflow would progress.
But instead, both ST1
and ST2
get executed instaed of just ST1
and moreover I get a bizarre execution and the flows are messed up.
I have another workflow like the below:
Both Wait1
& Wait2
have been set to PT2M
.
For test purposes, I use bpmn-client
to manually invoke the Receive Tasks.
I invoked RT1
alone using the Client API with a sample data.
I expect RT1
to be executed and the data gets recorded. After 2 mins, when Wait2
gets triggered, I expect the flow should be normal and shouldn't affect any other tasks or data.
After 2 mins, Wait2
gets triggerred. But at this stage, the data produced by RT1
gets deleted from the DB. And the execution is made to look like, RT1
never happened.
These issues seems quite critical and it is catastrophic to the data in the DB.
Kindly look into this.
Thank you.
Using 1.2
Calling deleteInstances
responds with a 404
error.
The API call is incorrect in BPMNClient.ts
at line 216.
URL should be datastore/deleteInstances
instead of datastore/delete
.
Thanks!
Hi @ralphhanna ,
First, thanks for this wonderful package.
In "bpmn-server", there are several examples on how to implement a Service Task in code using a custom MyAppDelegate.
In "bpmn-client", can we subscribe to a Service Task, and run code on the client when a Service Task needs to be run?
Hi @ralphhanna,
I am tring to execute remote import using the client. For some reason, it's not improting but no error too.
I have a BPMN file named diagram.bpmn
in the folder .workflows
of the working directory.
const { BPMNClient } = require("bpmn-client");
const path = require('path');
const dotenv = require("dotenv");
dotenv.config();
const server = new BPMNClient(
process.env.HOST,
process.env.PORT,
process.env.API_KEY
);
const rootPath = '';
const workflowsPath = path.join(__dirname, '.workflows');
console.log(`workflowsPath: ${workflowsPath}`);
const dataPath = path.join(workflowsPath, 'diagram.bpmn');
console.log(`dataPath: ${dataPath}`);
server.definitions.import('RTPDummy', dataPath);
bpmn-server
is running locally on port 3000
. .env
is configured correctly.
Cmd Output:
No Error. But the bpmn file is not imported into the server.
Could you please let me know what am I doing wrong?
Hi @ralphhanna,
Using bpmn-client
version 1.3.16
.
When I try to use cli.ts
to do some querying, all give the error:
BPMNClient 1.2
Commands:
q to quit
s start process
lo list outstanding items
li list items
l list instances for a process
di display Instance information
i Invoke Task
sgl Signal Task
msg Message Task
d delete instnaces
? repeat this list
Enter Command, q to quit
>lo
Listing Outstanding Items
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (F:\Programming\dicomHubScripts\node_modules\bpmn-client\src\BPMNClient.js:41:52)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
>di
Displaying Instance Details
Please provide your Instance ID: cd5f065a-a3b9-4189-85ad-4769d1527502
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (F:\Programming\dicomHubScripts\node_modules\bpmn-client\src\BPMNClient.js:41:52)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
>di
Displaying Instance Details
Please provide your Instance ID: "cd5f065a-a3b9-4189-85ad-4769d1527502"
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (F:\Programming\dicomHubScripts\node_modules\bpmn-client\src\BPMNClient.js:41:52)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Could you kindly look into this? Thank you!
When I use start, assign and invoke interface , it shows the user how do this action is undefined or null.
var client = new BPMNClient(process.env.HOST, process.env.PORT, process.env.API_KEY);
var response = await client.engine.start(processId, data, null, 'starter')
response = await client.engine.assign({ id: instance.id, "items.status": "wait" }, {}, 'starter', { assignee: 'starter' })
response = await client.engine.invoke({ id: instance.id, "items.status": "wait" }, {}, 'starter')
response = await clent.engine.assign({ id: instance.id, "items.status": "wait" }, {}, 'leader')
The request looks like succeed, but in the web it shows
12/3/2024 14:30:31 | Task Start a aproval process -Task_1 started.
12/3/2024 14:30:31 | Task Start a aproval process -Task_1 Assigned by undefined to:[object Object]
12/3/2024 14:30:31 | Task Start a aproval process ended by null
12/3/2024 14:30:31 | Task Level 1 approve -Task_2 started.
12/3/2024 14:30:31 | Task Level 1 approve -Task_2 Assigned by undefined to:[object Object]
For example, the code of the assign interface is:
async assign(query, data, userId = null, assignment): Promise<IInstanceData> {
const ret = await this.client.put('engine/assign', { query, data, userId, assignment });
if (ret['errors']) {
console.log(ret['errors']);
throw new Error(ret['errors']);
}
const instance = ret['instance'] as IInstanceData;
return instance;
}
In the request body of client,the user information is userId, it is not usable for server. In server it's userName.
Using 1.3.8
Hi @ralphhanna,
How to include messageMatchingKey
in throwSignal
& throwMessage
to target specific instances?
<?xml version="1.0" encoding="UTF-8"?>
<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:camunda="http://camunda.org/schema/1.0/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:signal id="Signal_1h6vd16" name="RedoProjSignal" />
<bpmn2:collaboration id="Collaboration_0go7gyp">
<bpmn2:participant id="Participant_1xfcqps" processRef="Process_1" />
</bpmn2:collaboration>
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:startEvent id="Event_1bj1934" name="Start Project">
<bpmn2:outgoing>Flow_1u6bj0c</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:serviceTask id="Activity_1hnnz2s" name="Approved">
<bpmn2:incoming>Flow_09bq1ec</bpmn2:incoming>
<bpmn2:outgoing>Flow_0nxka5r</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:serviceTask id="Activity_18guooz" name="Submission">
<bpmn2:incoming>Flow_1w1kljn</bpmn2:incoming>
<bpmn2:outgoing>Flow_1gvj1jf</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:userTask id="Activity_0kl39ez" name="Review by a colleague">
<bpmn2:incoming>Flow_006s1r5</bpmn2:incoming>
<bpmn2:outgoing>Flow_1w1kljn</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Activity_1mxe2wz" name="Do a project">
<bpmn2:incoming>Flow_1u6bj0c</bpmn2:incoming>
<bpmn2:incoming>Flow_0an1v3g</bpmn2:incoming>
<bpmn2:outgoing>Flow_006s1r5</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:endEvent id="Event_1xl3pr8" name="End Project">
<bpmn2:incoming>Flow_0nxka5r</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:intermediateCatchEvent id="Event_06dpucn" name="Redo Project">
<bpmn2:extensionElements>
<camunda:executionListener event="start">
<camunda:script scriptFormat="JavaScript">data.clientId=data.caseId;</camunda:script>
</camunda:executionListener>
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_1gvj1jf</bpmn2:incoming>
<bpmn2:outgoing>Flow_1anz4rf</bpmn2:outgoing>
<bpmn2:signalEventDefinition id="SignalEventDefinition_176nypw" signalRef="Signal_1h6vd16" />
</bpmn2:intermediateCatchEvent>
<bpmn2:exclusiveGateway id="Gateway_12fm9xs" name="isOkay" default="Flow_0an1v3g">
<bpmn2:incoming>Flow_1anz4rf</bpmn2:incoming>
<bpmn2:outgoing>Flow_09bq1ec</bpmn2:outgoing>
<bpmn2:outgoing>Flow_0an1v3g</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="Flow_0an1v3g" name="Not Okay" sourceRef="Gateway_12fm9xs" targetRef="Activity_1mxe2wz" />
<bpmn2:sequenceFlow id="Flow_09bq1ec" name="Okay" sourceRef="Gateway_12fm9xs" targetRef="Activity_1hnnz2s">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression" language="JavaScript">(item.data.isOkay === "Yes")</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="Flow_1anz4rf" sourceRef="Event_06dpucn" targetRef="Gateway_12fm9xs" />
<bpmn2:sequenceFlow id="Flow_0nxka5r" sourceRef="Activity_1hnnz2s" targetRef="Event_1xl3pr8" />
<bpmn2:sequenceFlow id="Flow_1gvj1jf" sourceRef="Activity_18guooz" targetRef="Event_06dpucn" />
<bpmn2:sequenceFlow id="Flow_1w1kljn" sourceRef="Activity_0kl39ez" targetRef="Activity_18guooz" />
<bpmn2:sequenceFlow id="Flow_006s1r5" sourceRef="Activity_1mxe2wz" targetRef="Activity_0kl39ez" />
<bpmn2:sequenceFlow id="Flow_1u6bj0c" sourceRef="Event_1bj1934" targetRef="Activity_1mxe2wz" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_0go7gyp">
<bpmndi:BPMNShape id="Participant_1xfcqps_di" bpmnElement="Participant_1xfcqps" isHorizontal="true">
<dc:Bounds x="120" y="80" width="1490" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1u6bj0c_di" bpmnElement="Flow_1u6bj0c">
<di:waypoint x="208" y="140" />
<di:waypoint x="320" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_006s1r5_di" bpmnElement="Flow_006s1r5">
<di:waypoint x="420" y="140" />
<di:waypoint x="530" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1w1kljn_di" bpmnElement="Flow_1w1kljn">
<di:waypoint x="630" y="140" />
<di:waypoint x="740" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1gvj1jf_di" bpmnElement="Flow_1gvj1jf">
<di:waypoint x="840" y="140" />
<di:waypoint x="962" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0nxka5r_di" bpmnElement="Flow_0nxka5r">
<di:waypoint x="1430" y="140" />
<di:waypoint x="1552" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1anz4rf_di" bpmnElement="Flow_1anz4rf">
<di:waypoint x="998" y="140" />
<di:waypoint x="1125" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_09bq1ec_di" bpmnElement="Flow_09bq1ec">
<di:waypoint x="1175" y="140" />
<di:waypoint x="1330" y="140" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1239" y="122" width="27" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0an1v3g_di" bpmnElement="Flow_0an1v3g">
<di:waypoint x="1150" y="165" />
<di:waypoint x="1150" y="250" />
<di:waypoint x="370" y="250" />
<di:waypoint x="370" y="180" />
<bpmndi:BPMNLabel>
<dc:Bounds x="737" y="232" width="47" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_1bj1934_di" bpmnElement="Event_1bj1934">
<dc:Bounds x="172" y="122" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="159" y="165" width="62" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1r8wbo4_di" bpmnElement="Activity_1hnnz2s">
<dc:Bounds x="1330" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_01lika7_di" bpmnElement="Activity_18guooz">
<dc:Bounds x="740" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0fu35gp_di" bpmnElement="Activity_0kl39ez">
<dc:Bounds x="530" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1le7cnc_di" bpmnElement="Activity_1mxe2wz">
<dc:Bounds x="320" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1xl3pr8_di" bpmnElement="Event_1xl3pr8">
<dc:Bounds x="1552" y="122" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1541" y="165" width="58" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_144odig_di" bpmnElement="Event_06dpucn">
<dc:Bounds x="962" y="122" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="947" y="98" width="65" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_12fm9xs_di" bpmnElement="Gateway_12fm9xs" isMarkerVisible="true">
<dc:Bounds x="1125" y="115" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1133" y="85" width="35" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
Signal ID: RedoProjSignal
Data Needed to sent: String variable isOkay
- Values Yes
or No
I know, the syntax for throwSignal
for the above would be:
server.engine.throwSignal("RedoProjSignal", {"isOkay": "Yes"});
BUT HOW TO ACCOMMODATE messageMatchingKey
in there?
<?xml version="1.0" encoding="UTF-8"?>
<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:camunda="http://camunda.org/schema/1.0/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:message id="Message_0fnszkw" name="ManualInspectDone" />
<bpmn2:collaboration id="Collaboration_1rvq0n9">
<bpmn2:participant id="Participant_0tn3rhm" processRef="Process_1" />
</bpmn2:collaboration>
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:startEvent id="StartEvent_1" name="Start">
<bpmn2:outgoing>Flow_1eoh9me</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:endEvent id="Event_1qoparn" name="End">
<bpmn2:incoming>Flow_0mgb1ux</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:intermediateCatchEvent id="Event_06use43" name="Manual Inspection">
<bpmn2:extensionElements>
<camunda:executionListener event="start">
<camunda:script scriptFormat="JavaScript">data.clientId=data.caseId;</camunda:script>
</camunda:executionListener>
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_0ttn3pa</bpmn2:incoming>
<bpmn2:outgoing>Flow_05qinuj</bpmn2:outgoing>
<bpmn2:messageEventDefinition id="MessageEventDefinition_0apns2b" messageRef="Message_0fnszkw" />
</bpmn2:intermediateCatchEvent>
<bpmn2:serviceTask id="Activity_047sfwk" name="Room Ready">
<bpmn2:incoming>Flow_05qinuj</bpmn2:incoming>
<bpmn2:outgoing>Flow_0mgb1ux</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:userTask id="Activity_0hgruvi" name="Checkout">
<bpmn2:incoming>Flow_1eoh9me</bpmn2:incoming>
<bpmn2:outgoing>Flow_1qvz91c</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:serviceTask id="Activity_0yhx8oi" name="Auto Inspection">
<bpmn2:incoming>Flow_1qvz91c</bpmn2:incoming>
<bpmn2:outgoing>Flow_0ttn3pa</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sequenceFlow id="Flow_0mgb1ux" sourceRef="Activity_047sfwk" targetRef="Event_1qoparn" />
<bpmn2:sequenceFlow id="Flow_05qinuj" sourceRef="Event_06use43" targetRef="Activity_047sfwk" />
<bpmn2:sequenceFlow id="Flow_0ttn3pa" sourceRef="Activity_0yhx8oi" targetRef="Event_06use43" />
<bpmn2:sequenceFlow id="Flow_1qvz91c" sourceRef="Activity_0hgruvi" targetRef="Activity_0yhx8oi" />
<bpmn2:sequenceFlow id="Flow_1eoh9me" sourceRef="StartEvent_1" targetRef="Activity_0hgruvi" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1rvq0n9">
<bpmndi:BPMNShape id="Participant_0tn3rhm_di" bpmnElement="Participant_0tn3rhm" isHorizontal="true">
<dc:Bounds x="190" y="90" width="1080" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1eoh9me_di" bpmnElement="Flow_1eoh9me">
<di:waypoint x="278" y="150" />
<di:waypoint x="380" y="150" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1qvz91c_di" bpmnElement="Flow_1qvz91c">
<di:waypoint x="480" y="150" />
<di:waypoint x="580" y="150" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ttn3pa_di" bpmnElement="Flow_0ttn3pa">
<di:waypoint x="680" y="150" />
<di:waypoint x="802" y="150" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_05qinuj_di" bpmnElement="Flow_05qinuj">
<di:waypoint x="838" y="150" />
<di:waypoint x="950" y="150" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0mgb1ux_di" bpmnElement="Flow_0mgb1ux">
<di:waypoint x="1050" y="150" />
<di:waypoint x="1212" y="150" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="242" y="132" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="248" y="175" width="25" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1qoparn_di" bpmnElement="Event_1qoparn">
<dc:Bounds x="1212" y="132" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1220" y="175" width="20" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_010yvpp_di" bpmnElement="Event_06use43">
<dc:Bounds x="802" y="132" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="776" y="175" width="90" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0b305kj_di" bpmnElement="Activity_047sfwk">
<dc:Bounds x="950" y="110" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1r89ccr_di" bpmnElement="Activity_0hgruvi">
<dc:Bounds x="380" y="110" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1s1xctl_di" bpmnElement="Activity_0yhx8oi">
<dc:Bounds x="580" y="110" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
Message ID: ManualInspectDone
Data Needed to sent: String variable doneBy
- Any text
I know, the syntax for throwMessage
for the above would be:
server.engine.throwMessage("ManualInspectDone", { "doneBy": "xxxx" });
BUT HOW TO ACCOMMODATE messageMatchingKey
in there?
Using 1.3.2
Hi @ralphhanna,
I'm trying to throw a signal from client side and catch that in a process.
<?xml version="1.0" encoding="UTF-8"?>
<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" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:startEvent id="Event_1bj1934" name="Start Project">
<bpmn2:outgoing>Flow_1u6bj0c</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="Flow_1u6bj0c" sourceRef="Event_1bj1934" targetRef="Activity_1mxe2wz" />
<bpmn2:sequenceFlow id="Flow_006s1r5" sourceRef="Activity_1mxe2wz" targetRef="Activity_0kl39ez" />
<bpmn2:sequenceFlow id="Flow_1w1kljn" sourceRef="Activity_0kl39ez" targetRef="Activity_18guooz" />
<bpmn2:sequenceFlow id="Flow_1gvj1jf" sourceRef="Activity_18guooz" targetRef="Event_06dpucn" />
<bpmn2:serviceTask id="Activity_1hnnz2s" name="Approved">
<bpmn2:incoming>Flow_09bq1ec</bpmn2:incoming>
<bpmn2:outgoing>Flow_0nxka5r</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:serviceTask id="Activity_18guooz" name="Submission">
<bpmn2:incoming>Flow_1w1kljn</bpmn2:incoming>
<bpmn2:outgoing>Flow_1gvj1jf</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:userTask id="Activity_0kl39ez" name="Review by a colleague">
<bpmn2:incoming>Flow_006s1r5</bpmn2:incoming>
<bpmn2:outgoing>Flow_1w1kljn</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Activity_1mxe2wz" name="Do a project">
<bpmn2:incoming>Flow_1u6bj0c</bpmn2:incoming>
<bpmn2:incoming>Flow_0an1v3g</bpmn2:incoming>
<bpmn2:outgoing>Flow_006s1r5</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:endEvent id="Event_1xl3pr8" name="End Project">
<bpmn2:incoming>Flow_0nxka5r</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_0nxka5r" sourceRef="Activity_1hnnz2s" targetRef="Event_1xl3pr8" />
<bpmn2:intermediateCatchEvent id="Event_06dpucn" name="Redo">
<bpmn2:incoming>Flow_1gvj1jf</bpmn2:incoming>
<bpmn2:outgoing>Flow_1anz4rf</bpmn2:outgoing>
<bpmn2:signalEventDefinition id="SignalEventDefinition_176nypw" signalRef="Signal_1h6vd16" />
</bpmn2:intermediateCatchEvent>
<bpmn2:exclusiveGateway id="Gateway_12fm9xs" name="isOkay">
<bpmn2:incoming>Flow_1anz4rf</bpmn2:incoming>
<bpmn2:outgoing>Flow_09bq1ec</bpmn2:outgoing>
<bpmn2:outgoing>Flow_0an1v3g</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="Flow_1anz4rf" sourceRef="Event_06dpucn" targetRef="Gateway_12fm9xs" />
<bpmn2:sequenceFlow id="Flow_09bq1ec" name="Okay" sourceRef="Gateway_12fm9xs" targetRef="Activity_1hnnz2s">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression" language="JavaScript">(item.data.isOkay === "Yes")</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="Flow_0an1v3g" name="Not Okay" sourceRef="Gateway_12fm9xs" targetRef="Activity_1mxe2wz" />
</bpmn2:process>
<bpmn2:signal id="Signal_0af9roe" name="redo_proj_signal" />
<bpmn2:signal id="Signal_1h6vd16" name="redo_proj_signal" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNEdge id="Flow_0nxka5r_di" bpmnElement="Flow_0nxka5r">
<di:waypoint x="1430" y="140" />
<di:waypoint x="1552" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1gvj1jf_di" bpmnElement="Flow_1gvj1jf">
<di:waypoint x="840" y="140" />
<di:waypoint x="962" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1w1kljn_di" bpmnElement="Flow_1w1kljn">
<di:waypoint x="630" y="140" />
<di:waypoint x="740" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_006s1r5_di" bpmnElement="Flow_006s1r5">
<di:waypoint x="420" y="140" />
<di:waypoint x="530" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1u6bj0c_di" bpmnElement="Flow_1u6bj0c">
<di:waypoint x="208" y="140" />
<di:waypoint x="320" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1anz4rf_di" bpmnElement="Flow_1anz4rf">
<di:waypoint x="998" y="140" />
<di:waypoint x="1125" y="140" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_09bq1ec_di" bpmnElement="Flow_09bq1ec">
<di:waypoint x="1175" y="140" />
<di:waypoint x="1330" y="140" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1239" y="122" width="27" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0an1v3g_di" bpmnElement="Flow_0an1v3g">
<di:waypoint x="1150" y="165" />
<di:waypoint x="1150" y="250" />
<di:waypoint x="370" y="250" />
<di:waypoint x="370" y="180" />
<bpmndi:BPMNLabel>
<dc:Bounds x="737" y="232" width="47" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_1bj1934_di" bpmnElement="Event_1bj1934">
<dc:Bounds x="172" y="122" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="159" y="165" width="62" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1r8wbo4_di" bpmnElement="Activity_1hnnz2s">
<dc:Bounds x="1330" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_01lika7_di" bpmnElement="Activity_18guooz">
<dc:Bounds x="740" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0fu35gp_di" bpmnElement="Activity_0kl39ez">
<dc:Bounds x="530" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1le7cnc_di" bpmnElement="Activity_1mxe2wz">
<dc:Bounds x="320" y="100" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1xl3pr8_di" bpmnElement="Event_1xl3pr8">
<dc:Bounds x="1552" y="122" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1541" y="165" width="58" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_144odig_di" bpmnElement="Event_06dpucn">
<dc:Bounds x="962" y="122" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="966" y="98" width="27" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_12fm9xs_di" bpmnElement="Gateway_12fm9xs" isMarkerVisible="true">
<dc:Bounds x="1125" y="115" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1133" y="85" width="35" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
import { BPMNClient } from "bpmn-client";
import * as readline from 'readline';
const dotenv = require('dotenv');
const res = dotenv.config();
const server = new BPMNClient(process.env.HOST, process.env.PORT, process.env.API_KEY);
const cl = readline.createInterface( process.stdin, process.stdout );
const question = function(q) {
return new Promise( (res, rej) => {
cl.question( q, answer => {
res(answer);
})
});
};
testUserInput();
async function testUserInput() {
console.log('Commands:');
console.log(' q To Quit');
console.log(' s Start Process ');
console.log(' lo List Outstanding Items');
console.log(' l List Instances for a Process');
console.log(' di Display Instance Details');
console.log(' i Invoke Task');
console.log(' sgl Signal Task');
console.log(' msg Message Task');
console.log(' d Delete Instances (Only those ended)');
let option='';
let command;
while(option!=='q')
{
command= await question('Enter Command, q to quit\n\r>');
let opts=command.split(' ');
option=opts[0];
switch(option)
{
case 'lo':
console.log("Listing Outstanding Items");
await findItems({ "items.status": "wait"});
break;
case 'l':
console.log("Listing Instances for a Process");
await listInstances();
break;
case 'di':
console.log("Displaying Instance Details");
await displayInstance();
break;
case 'i':
console.log("Invoking Task");
await invoke();
break;
case 's':
console.log("Starting Process");
await start();
break;
case 'sgl':
console.log("Signalling Process");
await signal();
break;
case 'msg':
console.log("Message Process");
await message();
break;
case 'd':
console.log("Deleting Instances (Only those ended)");
await delInstances();
break;
}
}
console.log("Bye");
cl.close();
}
async function start(){
const name = await question('Please provide your process name: ');
let taskData = await question('Please provide your Task Data (json obj) if any: ');
if (taskData === ""){
taskData = {};
}else{
taskData = JSON.parse(taskData.toString());
}
let response=await server.engine.start(name, taskData);
console.log("Process '"+name+"' started; InstanceId",response.id);
}
async function findItems(query) {
var items = await server.datastore.findItems(query);
console.log(items);
for (var i = 0; i < items.length; i++) {
let item = items[i];
console.log(`${item.name} - ${item.elementId} InstanceId: ${item['instanceId']}`);
}
}
async function listInstances() {
const name = await question('Please provide your process name: ');
let insts = await server.datastore.findInstances({ name: name})
for (var i = 0; i < insts.length; i++) {
let inst = insts[i];
console.log(`Name: ${inst.name} Status: ${inst.status} InstanceId: ${inst.id}
StartedAt: ${inst.startedAt} EndedAt ${inst.endedAt}`, 'Data:', inst.data);
}
}
async function displayInstance() {
const instanceId = await question('Please provide your Instance ID: ');
let insts = await server.datastore.findInstances({id: instanceId})
for (var i = 0; i < insts.length; i++) {
let inst = insts[i];
var items = inst.items;
console.log(`Name: ${inst.name} Status: ${inst.status} InstanceId: ${inst.id}
StartedAt: ${inst.startedAt} EndedAt ${inst.endedAt}`,'Data:', inst.data);
for (var j = 0; j < items.length; j++) {
let item= items[j];
console.log(` Element: ${item.elementId} Status: ${item.status} Id: ${item.id}`);
}
}
}
async function invoke(){
const instanceId = await question('Please provide your Instance ID: ');
const taskId = await question('Please provide your Task ID: ');
let taskData = await question('Please provide your Task Data (json obj) if any: ');
if (taskData === ""){
taskData = {};
}else{
taskData = JSON.parse(taskData.toString());
}
try {
let response = await server.engine.invoke(
{ id: instanceId, "items.elementId": taskId }
, taskData);
console.log("Completed UserTask:", taskId);
}
catch (exc) {
console.log("Invoking task failed for:", taskId, instanceId);
await findItems({ id: instanceId, "items.elementId": taskId });
}
}
async function signal() {
const signalId = await question('Please provide signal ID: ');
let signalData = await question('Please provide your Data (json obj) if any: ');
if (typeof signalData === 'string' && signalData.trim() === ''){
signalData = {};
}else{
signalData = JSON.parse(signalData.toString());
}
let response = await server.engine.throwSignal(signalId, signalData);
console.log("Signal Response:", response);
}
async function message() {
const messageId = await question('Please provide message ID: ');
let messageData = await question('Please provide your Data (json obj) if any: ');
if (typeof messageData === 'string' && messageData.trim() === ''){
messageData = {};
}else{
messageData = JSON.parse(messageData.toString());
}
let response = await server.engine.throwMessage(messageId, messageData);
console.log("Message Response:", response);
}
async function delInstances() {
const name = await question('Please provide process name to delete instances: ');
let response = await server.datastore.deleteInstances({ name: name, status: "end" });
console.log("Instances Deleted:", response['result']['deletedCount']);
}
>node testCLI.js
BPMNClient 1.2
Commands:
q To Quit
s Start Process
lo List Outstanding Items
l List Instances for a Process
di Display Instance Details
i Invoke Task
sgl Signal Task
msg Message Task
d Delete Instances (Only those ended)
Enter Command, q to quit
>sgl
Signalling Process
Please provide signal ID: redo_proj_signal
Please provide your Data (json obj) if any:
undefined:1
<!DOCTYPE html>
^
SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (F:\Programming\Test-BPMN-Client\node_modules\bpmn-client\src\BPMNClient.js:39:48)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Node.js v18.7.0
This also applies to throwMessage
method.
Kindly look into this. Thanks!
Hi @ralphhanna,
Could you please add vars
to the interface DataObjects.ts
as well?
Also, could you please make sure the changes reflect in the npm
package as well; the last PR isn't reflected in that?
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.