@5minds/node-red-contrib-processcube 1.8.3 → 1.8.5-develop-e1e2dc-m7pcoei4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -698,17 +698,6 @@
|
|
698
698
|
"name": "Engine Auth 8000",
|
699
699
|
"url": "http://engine:8000"
|
700
700
|
},
|
701
|
-
{
|
702
|
-
"id": "f7961bee80d8bcb5",
|
703
|
-
"type": "processcube-engine-config",
|
704
|
-
"name": "",
|
705
|
-
"url": "http://engine:8001",
|
706
|
-
"urlType": "str",
|
707
|
-
"clientId": "",
|
708
|
-
"clientIdType": "str",
|
709
|
-
"clientSecret": "",
|
710
|
-
"clientSecretType": "str"
|
711
|
-
},
|
712
701
|
{
|
713
702
|
"id": "b7ddfedf82d8120f",
|
714
703
|
"type": "externaltask-error",
|
@@ -818,7 +807,7 @@
|
|
818
807
|
"z": "a23d2e782beb66f4",
|
819
808
|
"g": "31cb6729aac0ba46",
|
820
809
|
"name": "raise Error",
|
821
|
-
"func": "throw Error(\"hello error\")
|
810
|
+
"func": "const randomDelay = Math.floor(Math.random() * (10000 - 1000 + 1)) + 1000; // Zufall zwischen 1000 und 10000 ms\n\nsetTimeout(() => {\n node.send(msg);\n}, randomDelay);\n\n//throw Error(\"hello error\");",
|
822
811
|
"outputs": 1,
|
823
812
|
"timeout": 0,
|
824
813
|
"noerr": 0,
|
@@ -1172,7 +1161,7 @@
|
|
1172
1161
|
"z": "a23d2e782beb66f4",
|
1173
1162
|
"g": "70d7a70e375b162a",
|
1174
1163
|
"name": "debug 3",
|
1175
|
-
"active":
|
1164
|
+
"active": false,
|
1176
1165
|
"tosidebar": true,
|
1177
1166
|
"console": false,
|
1178
1167
|
"tostatus": false,
|
@@ -2616,7 +2605,7 @@
|
|
2616
2605
|
"type": "debug",
|
2617
2606
|
"z": "76c047e0d8770a20",
|
2618
2607
|
"name": "debug 34",
|
2619
|
-
"active":
|
2608
|
+
"active": false,
|
2620
2609
|
"tosidebar": true,
|
2621
2610
|
"console": false,
|
2622
2611
|
"tostatus": false,
|
package/docker-compose.yml
CHANGED
@@ -14,7 +14,8 @@ services:
|
|
14
14
|
- TOPIC=TopicFromENV
|
15
15
|
# start node-red with debugger port open
|
16
16
|
- NODE_OPTIONS=--inspect=0.0.0.0:9229
|
17
|
-
- NODE_RED_ETW_HEARTBEAT_LOGGING=
|
17
|
+
- NODE_RED_ETW_HEARTBEAT_LOGGING=false
|
18
|
+
- NODE_RED_ETW_STEP_LOGGING=true
|
18
19
|
volumes:
|
19
20
|
# required for mapping the current source into the directory
|
20
21
|
- ./.:/package_src/
|
package/externaltask-input.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
const EventEmitter = require('node:events');
|
2
|
+
const { send } = require('node:process');
|
2
3
|
|
3
4
|
|
4
5
|
module.exports = function (RED) {
|
@@ -14,10 +15,114 @@ module.exports = function (RED) {
|
|
14
15
|
|
15
16
|
let options = RED.util.evaluateNodeProperty(config.workerConfig, config.workerConfigType, node);
|
16
17
|
let topic = node.topic = RED.util.evaluateNodeProperty(config.topic, config.topicType, node)
|
17
|
-
|
18
|
-
|
18
|
+
|
19
19
|
node._subscribed = true;
|
20
20
|
node._subscribed_error = null;
|
21
|
+
node._trace = '';
|
22
|
+
node._step = '';
|
23
|
+
node._tracking_nodes = {};
|
24
|
+
node._tracking_for_etw = {};
|
25
|
+
|
26
|
+
node.isHandling = () => {
|
27
|
+
return Object.keys(node.started_external_tasks).length > 0;
|
28
|
+
};
|
29
|
+
|
30
|
+
node.ownMessage = (msg) => {
|
31
|
+
return msg.etw_input_node_id === node.id;
|
32
|
+
};
|
33
|
+
|
34
|
+
node.clearTracking = (msg) => {
|
35
|
+
if (msg.flowNodeInstanceId) {
|
36
|
+
node._tracking_for_etw[msg.flowNodeInstanceId].forEach((theNode) => {
|
37
|
+
node.decrMsgOnNode(theNode, msg);
|
38
|
+
});
|
39
|
+
}
|
40
|
+
};
|
41
|
+
|
42
|
+
node.incMsgOnNode = (theNode, msg) => {
|
43
|
+
if (node.id === theNode.id) {
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
|
47
|
+
if (!node._tracking_nodes[theNode.id]) {
|
48
|
+
node._tracking_nodes[theNode.id] = {
|
49
|
+
node: theNode,
|
50
|
+
count: 1,
|
51
|
+
};
|
52
|
+
} else {
|
53
|
+
node._tracking_nodes[theNode.id].count++;
|
54
|
+
}
|
55
|
+
|
56
|
+
if (!node._tracking_for_etw[msg.flowNodeInstanceId]) {
|
57
|
+
node._tracking_for_etw[msg.flowNodeInstanceId] = [];
|
58
|
+
node._tracking_for_etw[msg.flowNodeInstanceId].push(theNode);
|
59
|
+
} else {
|
60
|
+
node._tracking_for_etw[msg.flowNodeInstanceId].push(theNode);
|
61
|
+
}
|
62
|
+
|
63
|
+
theNode.status({ fill: 'green', shape: 'dot', text: `tasks(${node._tracking_nodes[theNode.id].count}).` });
|
64
|
+
};
|
65
|
+
|
66
|
+
node.decrMsgOnNode = (theNode, msg) => {
|
67
|
+
if (node.id === theNode.id) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
|
71
|
+
if (!node._tracking_nodes[theNode.id]) {
|
72
|
+
node._tracking_nodes[theNode.id] = {
|
73
|
+
node: theNode,
|
74
|
+
count: 0,
|
75
|
+
};
|
76
|
+
} else {
|
77
|
+
node._tracking_nodes[theNode.id].count--;
|
78
|
+
|
79
|
+
if (node._tracking_nodes[theNode.id].count <= 0) {
|
80
|
+
node._tracking_nodes[theNode.id].count = 0;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
if (node._tracking_for_etw[msg.flowNodeInstanceId]) {
|
85
|
+
node._tracking_for_etw[msg.flowNodeInstanceId] = node._tracking_for_etw[msg.flowNodeInstanceId].filter(item => item !== theNode)
|
86
|
+
|
87
|
+
if (node._tracking_for_etw[msg.flowNodeInstanceId].count <= 0) {
|
88
|
+
delete node._tracking_for_etw[msg.flowNodeInstanceId];
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
theNode.status({ fill: 'green', shape: 'dot', text: `tasks(${node._tracking_nodes[theNode.id].count}).` });
|
93
|
+
};
|
94
|
+
|
95
|
+
RED.hooks.add('preDeliver', (sendEvent) => {
|
96
|
+
if (node.isHandling() && node.ownMessage(sendEvent.msg)) {
|
97
|
+
|
98
|
+
const sourceNode = sendEvent?.source?.node;
|
99
|
+
const destinationNode = sendEvent?.destination?.node;
|
100
|
+
|
101
|
+
node._step = `${destinationNode.name || destinationNode.type}`;
|
102
|
+
|
103
|
+
node.showStatus();
|
104
|
+
|
105
|
+
if (process.env.NODE_RED_ETW_STEP_LOGGING == 'true') {
|
106
|
+
node._trace = `'${sourceNode.name || sourceNode.type}'->'${destinationNode.name || destinationNode.type}'`;
|
107
|
+
node.log(`preDeliver: ${node._trace}`);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
});
|
111
|
+
|
112
|
+
RED.hooks.add('postDeliver', (sendEvent) => {
|
113
|
+
if (node.isHandling() && node.ownMessage(sendEvent.msg)) {
|
114
|
+
const sourceNode = sendEvent?.source?.node;
|
115
|
+
const destinationNode = sendEvent?.destination?.node;
|
116
|
+
|
117
|
+
node.decrMsgOnNode(sourceNode, sendEvent.msg);
|
118
|
+
node.incMsgOnNode(destinationNode, sendEvent.msg);
|
119
|
+
|
120
|
+
if (process.env.NODE_RED_ETW_STEP_LOGGING == 'true') {
|
121
|
+
node._trace = `'${sourceNode.name || sourceNode.type}'->'${destinationNode.name || destinationNode.type}'`;
|
122
|
+
node.log(`postDeliver: ${node._trace}`);
|
123
|
+
}
|
124
|
+
}
|
125
|
+
});
|
21
126
|
|
22
127
|
node.setSubscribedStatus = () => {
|
23
128
|
this._subscribed = true;
|
@@ -30,7 +135,7 @@ module.exports = function (RED) {
|
|
30
135
|
this._subscribed_error = error;
|
31
136
|
|
32
137
|
this.error(`subscription failed (topic: ${node.topic}).`);
|
33
|
-
RED.log.error(`topic: ${node.topic} (${error
|
138
|
+
RED.log.error(`topic: ${node.topic} (${error?.message}).`);
|
34
139
|
|
35
140
|
this.showStatus();
|
36
141
|
};
|
@@ -46,11 +151,14 @@ module.exports = function (RED) {
|
|
46
151
|
node.setFinishHandlingTaskStatus = (externalTask) => {
|
47
152
|
if (externalTask.flowNodeInstanceId) {
|
48
153
|
delete this.started_external_tasks[externalTask.flowNodeInstanceId];
|
154
|
+
node._trace = '';
|
155
|
+
node._step = '';
|
49
156
|
}
|
50
157
|
|
51
158
|
this._subscribed = true;
|
52
159
|
this._subscribed_error = null;
|
53
160
|
|
161
|
+
this.clearTracking(externalTask); // as msg
|
54
162
|
this.showStatus();
|
55
163
|
};
|
56
164
|
|
@@ -61,7 +169,7 @@ module.exports = function (RED) {
|
|
61
169
|
|
62
170
|
this._subscribed_error = error;
|
63
171
|
this.error(`finished task failed (topic: ${node.topic}).`);
|
64
|
-
RED.log.error(`topic: ${node.topic} (${error
|
172
|
+
RED.log.error(`topic: ${node.topic} (${error?.message}).`);
|
65
173
|
|
66
174
|
this.showStatus();
|
67
175
|
};
|
@@ -70,13 +178,50 @@ module.exports = function (RED) {
|
|
70
178
|
const msgCounter = Object.keys(this.started_external_tasks).length;
|
71
179
|
|
72
180
|
if (this._subscribed === false) {
|
73
|
-
this.status({ fill: 'red', shape: 'ring', text: `subscription failed (${msgCounter}).` })
|
181
|
+
this.status({ fill: 'red', shape: 'ring', text: `subscription failed (${msgCounter}).` });
|
182
|
+
|
183
|
+
RED.events.emit("processcube:healthcheck:update", {
|
184
|
+
nodeId: node.id,
|
185
|
+
status: 'NotOk',
|
186
|
+
nodeName: node.name,
|
187
|
+
nodeType: 'externaltask-input',
|
188
|
+
message: `subscription failed (${msgCounter}).`
|
189
|
+
});
|
74
190
|
} else {
|
75
191
|
if (msgCounter >= 1) {
|
76
|
-
|
192
|
+
if (node._step) {
|
193
|
+
this.status({ fill: 'green', shape: 'dot', text: `tasks(${msgCounter}) ->'${node._step}'.` });
|
194
|
+
|
195
|
+
RED.events.emit("processcube:healthcheck:update", {
|
196
|
+
nodeId: node.id,
|
197
|
+
status: 'Ok',
|
198
|
+
nodeName: node.name,
|
199
|
+
nodeType: 'externaltask-input',
|
200
|
+
message: `tasks(${msgCounter}) ->'${node._step}'.`
|
201
|
+
});
|
202
|
+
|
203
|
+
} else {
|
204
|
+
this.status({ fill: 'green', shape: 'dot', text: `tasks(${msgCounter}).` });
|
205
|
+
|
206
|
+
RED.events.emit("processcube:healthcheck:update", {
|
207
|
+
nodeId: node.id,
|
208
|
+
status: 'Ok',
|
209
|
+
nodeName: node.name,
|
210
|
+
nodeType: 'externaltask-input',
|
211
|
+
message: `tasks(${msgCounter}).`
|
212
|
+
});
|
213
|
+
}
|
77
214
|
this.log(`handling tasks ${msgCounter}.`);
|
78
215
|
} else {
|
79
216
|
this.status({ fill: 'blue', shape: 'ring', text: `subcribed.` });
|
217
|
+
|
218
|
+
RED.events.emit("processcube:healthcheck:update", {
|
219
|
+
nodeId: node.id,
|
220
|
+
status: 'Ok',
|
221
|
+
nodeName: node.name,
|
222
|
+
nodeType: 'externaltask-input',
|
223
|
+
message: `subcribed.`
|
224
|
+
});
|
80
225
|
}
|
81
226
|
}
|
82
227
|
};
|
@@ -101,11 +246,12 @@ module.exports = function (RED) {
|
|
101
246
|
const saveHandleCallback = (data, callback, msg) => {
|
102
247
|
try {
|
103
248
|
callback(data);
|
249
|
+
node.log(`send to engine *external task flowNodeInstanceId* '${externalTask.flowNodeInstanceId}' and *processInstanceId* ${externalTask.processInstanceId}`);
|
104
250
|
node.setFinishHandlingTaskStatus(externalTask);
|
105
251
|
} catch (error) {
|
106
252
|
node.setErrorFinishHandlingTaskStatus(externalTask, error);
|
107
253
|
msg.error = error;
|
108
|
-
node.error(`
|
254
|
+
node.error(`failed send to engine *external task flowNodeInstanceId* '${externalTask.flowNodeInstanceId}' and *processInstanceId* ${externalTask.processInstanceId}: ${erro?.message}`, msg);
|
109
255
|
}
|
110
256
|
};
|
111
257
|
|
@@ -125,16 +271,16 @@ module.exports = function (RED) {
|
|
125
271
|
saveHandleCallback(result, resolve, msg);
|
126
272
|
};
|
127
273
|
|
128
|
-
const handleErrorTask = (
|
274
|
+
const handleErrorTask = (error) => {
|
129
275
|
node.log(
|
130
|
-
`handle error event for *external task flowNodeInstanceId* '${externalTask.flowNodeInstanceId}' and *processInstanceId* '${externalTask.processInstanceId}' on *msg._msgid* '${
|
276
|
+
`handle error event for *external task flowNodeInstanceId* '${externalTask.flowNodeInstanceId}' and *processInstanceId* '${externalTask.processInstanceId}' on *msg._msgid* '${error.errorDetails?._msgid}'.`
|
131
277
|
);
|
132
278
|
|
133
279
|
// TODO: with reject, the default error handling is proceed
|
134
280
|
// SEE: https://github.com/5minds/ProcessCube.Engine.Client.ts/blob/develop/src/ExternalTaskWorker.ts#L180
|
135
281
|
// reject(result);
|
136
282
|
//resolve(msg);
|
137
|
-
saveHandleCallback(
|
283
|
+
saveHandleCallback(error, resolve, error);
|
138
284
|
};
|
139
285
|
|
140
286
|
node.eventEmitter.once(`handle-${externalTask.flowNodeInstanceId}`, (msg, isError = false) => {
|
@@ -178,7 +324,7 @@ module.exports = function (RED) {
|
|
178
324
|
externalTaskWorker.onHeartbeat((event, external_task_id) => {
|
179
325
|
node.setSubscribedStatus();
|
180
326
|
|
181
|
-
if (process.env.NODE_RED_ETW_HEARTBEAT_LOGGING) {
|
327
|
+
if (process.env.NODE_RED_ETW_HEARTBEAT_LOGGING == 'true') {
|
182
328
|
if (external_task_id) {
|
183
329
|
this.log(`subscription (heartbeat:topic ${node.topic}, ${event} for ${external_task_id}).`);
|
184
330
|
} else {
|
@@ -193,13 +339,9 @@ module.exports = function (RED) {
|
|
193
339
|
case 'finishExternalTask':
|
194
340
|
case 'processExternalTask':
|
195
341
|
node.error(
|
196
|
-
`Worker error ${errorType} for *external task flowNodeInstanceId* '${externalTask.flowNodeInstanceId}' and *processInstanceId* '${externalTask.processInstanceId}': ${error
|
342
|
+
`Worker error ${errorType} for *external task flowNodeInstanceId* '${externalTask.flowNodeInstanceId}' and *processInstanceId* '${externalTask.processInstanceId}': ${error?.message}`
|
197
343
|
);
|
198
344
|
|
199
|
-
//if (externalTask) {
|
200
|
-
// delete node.started_external_tasks[externalTask.flowNodeInstanceId];
|
201
|
-
//}
|
202
|
-
|
203
345
|
node.setUnsubscribedStatus(error);
|
204
346
|
|
205
347
|
break;
|
package/package.json
CHANGED
@@ -9,9 +9,6 @@
|
|
9
9
|
</bpmn:collaboration>
|
10
10
|
<bpmn:process id="External-Task-Sample_Process" name="External-Task-Sample" isExecutable="true">
|
11
11
|
<bpmn:laneSet />
|
12
|
-
<bpmn:startEvent id="StartEvent_1" name="Start">
|
13
|
-
<bpmn:outgoing>Flow_0qmxzxk</bpmn:outgoing>
|
14
|
-
</bpmn:startEvent>
|
15
12
|
<bpmn:sequenceFlow id="Flow_0qmxzxk" sourceRef="StartEvent_1" targetRef="Activity_02ykwt2" />
|
16
13
|
<bpmn:sequenceFlow id="Flow_16dfeac" sourceRef="Activity_02ykwt2" targetRef="Activity_0ma3kzt" />
|
17
14
|
<bpmn:endEvent id="Event_05wpeos">
|
@@ -23,6 +20,11 @@
|
|
23
20
|
</bpmn:endEvent>
|
24
21
|
<bpmn:sequenceFlow id="Flow_0y6es1p" sourceRef="Event_0o7qlkd" targetRef="Event_0yn9mzh" />
|
25
22
|
<bpmn:serviceTask id="Activity_02ykwt2" name="Topic "Test"" camunda:type="external" camunda:topic="Test">
|
23
|
+
<bpmn:extensionElements>
|
24
|
+
<camunda:properties>
|
25
|
+
<camunda:property name="payload" value="{ "hello": "world" }" />
|
26
|
+
</camunda:properties>
|
27
|
+
</bpmn:extensionElements>
|
26
28
|
<bpmn:incoming>Flow_0qmxzxk</bpmn:incoming>
|
27
29
|
<bpmn:outgoing>Flow_16dfeac</bpmn:outgoing>
|
28
30
|
</bpmn:serviceTask>
|
@@ -42,6 +44,17 @@
|
|
42
44
|
<bpmn:outgoing>Flow_1fsn04u</bpmn:outgoing>
|
43
45
|
<bpmn:errorEventDefinition id="ErrorEventDefinition_0kojqkb" errorRef="Error_TrRFOiMy" />
|
44
46
|
</bpmn:boundaryEvent>
|
47
|
+
<bpmn:startEvent id="StartEvent_1" name="Start">
|
48
|
+
<bpmn:extensionElements>
|
49
|
+
<camunda:properties>
|
50
|
+
<camunda:property name="enabled" value="false" />
|
51
|
+
</camunda:properties>
|
52
|
+
</bpmn:extensionElements>
|
53
|
+
<bpmn:outgoing>Flow_0qmxzxk</bpmn:outgoing>
|
54
|
+
<bpmn:timerEventDefinition id="TimerEventDefinition_02zdsh9">
|
55
|
+
<bpmn:timeCycle xsi:type="bpmn:tFormalExpression">*/10 * * * * *</bpmn:timeCycle>
|
56
|
+
</bpmn:timerEventDefinition>
|
57
|
+
</bpmn:startEvent>
|
45
58
|
</bpmn:process>
|
46
59
|
<bpmn:error id="Error_3O8wBFQi" errorCode="MyErrorCode" />
|
47
60
|
<bpmn:error id="Error_TrRFOiMy" errorCode="handleSubFlowError" />
|
@@ -50,12 +63,6 @@
|
|
50
63
|
<bpmndi:BPMNShape id="Participant_0px403d_di" bpmnElement="Participant_0px403d" isHorizontal="true">
|
51
64
|
<dc:Bounds x="5" y="30" width="635" height="320" />
|
52
65
|
</bpmndi:BPMNShape>
|
53
|
-
<bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
|
54
|
-
<dc:Bounds x="92" y="152" width="36" height="36" />
|
55
|
-
<bpmndi:BPMNLabel>
|
56
|
-
<dc:Bounds x="98" y="195" width="24" height="14" />
|
57
|
-
</bpmndi:BPMNLabel>
|
58
|
-
</bpmndi:BPMNShape>
|
59
66
|
<bpmndi:BPMNShape id="Event_05wpeos_di" bpmnElement="Event_05wpeos">
|
60
67
|
<dc:Bounds x="502" y="152" width="36" height="36" />
|
61
68
|
</bpmndi:BPMNShape>
|
@@ -73,6 +80,12 @@
|
|
73
80
|
<bpmndi:BPMNShape id="Event_0rs3geg_di" bpmnElement="Event_0rs3geg">
|
74
81
|
<dc:Bounds x="312" y="272" width="36" height="36" />
|
75
82
|
</bpmndi:BPMNShape>
|
83
|
+
<bpmndi:BPMNShape id="Event_00jrf2t_di" bpmnElement="StartEvent_1">
|
84
|
+
<dc:Bounds x="92" y="152" width="36" height="36" />
|
85
|
+
<bpmndi:BPMNLabel>
|
86
|
+
<dc:Bounds x="98" y="195" width="24" height="14" />
|
87
|
+
</bpmndi:BPMNLabel>
|
88
|
+
</bpmndi:BPMNShape>
|
76
89
|
<bpmndi:BPMNShape id="Event_03ytp91_di" bpmnElement="Event_007u06e">
|
77
90
|
<dc:Bounds x="222" y="192" width="36" height="36" />
|
78
91
|
</bpmndi:BPMNShape>
|