@5minds/node-red-contrib-processcube 1.5.12 → 1.6.0-develop-dc8225-m4wqtshx

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-contrib-processcube",
3
- "version": "1.5.12",
3
+ "version": "1.6.0-develop-dc8225-m4wqtshx",
4
4
  "license": "MIT",
5
5
  "description": "Node-RED nodes for ProcessCube",
6
6
  "scripts": {
@@ -7,7 +7,7 @@
7
7
  engine: { value: '', type: 'processcube-engine-config' },
8
8
  modelid: { value: '' },
9
9
  duration: { value: '', type: 'number' },
10
- time_unit: { value: 'hours' },
10
+ time_type: { value: '' },
11
11
  batch_size: { value: '100', type: 'number' },
12
12
  },
13
13
  inputs: 1,
@@ -37,8 +37,8 @@
37
37
  <input type="text" id="node-input-duration" />
38
38
  </div>
39
39
  <div class="form-row">
40
- <label for="node-input-time_unit"><i class="fa fa-sliders"></i> Time Unit</label>
41
- <select id="node-input-time_unit" style="width: 70%;">
40
+ <label for="node-input-time_type"><i class="fa fa-sliders"></i> Time Unit</label>
41
+ <select id="node-input-time_type" style="width: 70%;">
42
42
  <option value="hours">Hours</option>
43
43
  <option value="days">Days</option>
44
44
  </select>
@@ -55,7 +55,7 @@ Delete old instances of a process model in the ProcessCube.
55
55
  ## Inputs
56
56
 
57
57
  : payload.duration (number): The number of given time periods.
58
- : payload.time_unit ('hours' | 'days'): The type of time period to use.
58
+ : payload.time_type ('hours' | 'days'): The type of time period to use.
59
59
  : payload.batch_size (number): The number of instances to be deleted simultaneously. (default 100)
60
60
 
61
61
  ## Outputs
@@ -1,72 +1,100 @@
1
1
  module.exports = function (RED) {
2
2
  function ProcessInstanceDelete(config) {
3
3
  RED.nodes.createNode(this, config);
4
- var node = this;
4
+ const node = this;
5
5
 
6
6
  node.on('input', async function (msg) {
7
7
  node.engine = RED.nodes.getNode(config.engine);
8
- const client = node.engine.engineClient;
8
+ const client = node.engine ? node.engine.engineClient : null;
9
9
 
10
- if (!client) {
11
- node.error('No engine configured.');
10
+ if (!client || !client.processInstances) {
11
+ node.error('No engine or processInstances API configured.');
12
12
  return;
13
13
  }
14
14
 
15
- let timeMultiplier;
16
- if (msg.payload.time_unit) {
17
- timeMultiplier = msg.payload.time_unit == 'hours' ? 1 : 24;
18
- } else {
19
- timeMultiplier = config.time_unit == 'hours' ? 1 : 24;
15
+ const timeToUse = msg.payload.duration || config.duration;
16
+ if (!timeToUse || isNaN(timeToUse) || timeToUse <= 0) {
17
+ node.error('Invalid duration: must be a positive number.');
18
+ return;
20
19
  }
21
20
 
22
- const timeToUse = msg.payload.duration ? msg.payload.duration : config.duration;
23
- const modelId = msg.payload.processModelId
24
- ? msg.payload.processModelId != ''
25
- ? msg.payload.processModelId
26
- : undefined
27
- : config.modelid != ''
28
- ? config.modelid
29
- : undefined;
21
+ // Gültige Werte für time_type
22
+ const validTimeTypes = ['days', 'hours'];
23
+ const timeType = msg.payload.time_type
24
+ ? msg.payload.time_type.toLowerCase()
25
+ : config.time_type?.toLowerCase();
30
26
 
31
- const batchSize = config.batch_size || 100; // Konfigurierbare Batchgröße, Standardwert 100
27
+ // time_type validieren
28
+ if (!timeType || !validTimeTypes.includes(timeType)) {
29
+ node.error(`Invalid time_type provided: ${timeType}. Allowed values are 'days' or 'hours'.`);
30
+ return;
31
+ }
32
32
 
33
- try {
34
- const result = await client.processInstances.query({
35
- processModelId: modelId
36
- }, { identity: node.engine.identity });
33
+ // Zeitmultiplikator berechnen
34
+ const multiplier = timeType === 'hours' ? 1 : 24;
35
+ node.log(`Time type: ${timeType}`);
36
+
37
+ const deletionDate = new Date(Date.now() - timeToUse * multiplier * 60 * 60 * 1000);
38
+
39
+ const modelId = msg.payload.processModelId?.trim() || config.modelid?.trim();
40
+ if (!modelId) {
41
+ node.error('processModelId is not defined or empty.');
42
+ return;
43
+ }
37
44
 
38
- let allInstances = result.processInstances.filter((instance) => instance.state != 'suspended' && instance.state != 'running');
45
+ // Prüfung und Festlegung von batch_size
46
+ let batchSize = msg.payload.batch_size || config.batch_size || 1000;
47
+ if (isNaN(batchSize) || batchSize <= 0 || batchSize > 1000) {
48
+ node.error(`Invalid batch_size: ${batchSize}. Must be a positive number and not exceed 1000.`);
49
+ return;
50
+ }
51
+ batchSize = Math.min(batchSize, 1000); // Sicherstellen, dass der Wert 1000 nicht überschreitet
39
52
 
40
- const today = new Date();
53
+ try {
54
+ msg.payload = { successfulDeletions: [], failedDeletions: [] };
41
55
 
42
- const oldTasks = allInstances.filter((instance) => {
43
- const finishedDate = new Date(instance.finishedAt);
44
- const diffInHours = (today - finishedDate) / (1000 * 60 * 60);
45
- return diffInHours > Number(timeToUse) * timeMultiplier;
46
- });
56
+ let hasMoreResults = true;
57
+ let sumSuccessful = 0;
58
+ let sumFailed = 0;
59
+ while (hasMoreResults) {
60
+ const result = await client.processInstances.query(
61
+ {
62
+ processModelId: modelId,
63
+ finishedBefore: deletionDate.toISOString(),
64
+ state: ['finished', 'error', 'terminated'],
65
+ limit: batchSize,
66
+ },
67
+ { includeXml: false }
68
+ );
47
69
 
48
- const ids = oldTasks.map((obj) => obj.processInstanceId);
70
+ const processInstances = result.processInstances || [];
71
+ if (processInstances.length === 0) {
72
+ node.log(`No more process instances to delete for Model-ID: ${modelId} with Date: ${deletionDate.toISOString()}`);
73
+ hasMoreResults = false;
74
+ continue;
75
+ }
49
76
 
50
- msg.payload = {
51
- successfulDeletions: [],
52
- failedDeletions: []
53
- };
77
+ const ids = processInstances.map((obj) => obj.processInstanceId);
54
78
 
55
- for (let i = 0; i < ids.length; i += batchSize) {
56
- const batch = ids.slice(i, i + batchSize);
57
79
  try {
58
- await client.processInstances.deleteProcessInstances(batch, true, engine.identity);
59
- msg.payload.successfulDeletions.push(...batch); // Erfolgreiche IDs hinzufügen
80
+ await client.processInstances.deleteProcessInstances(ids, true);
81
+ msg.payload.successfulDeletions.push(...ids);
82
+ sumSuccessful += ids.length;
60
83
  } catch (deleteError) {
61
- batch.forEach(id => {
62
- msg.payload.failedDeletions.push({ id, error: deleteError.message }); // Fehler protokollieren
84
+ var message = JSON.stringify(deleteError);
85
+ sumFailed += ids.length;
86
+ ids.forEach((id) => {
87
+ msg.payload.failedDeletions.push({ id, error: message });
63
88
  });
64
- node.warn(`Failed to delete process instances in batch: ${batch.join(', ')}. Error: ${deleteError.message}`);
89
+ node.warn(`Failed to delete some process instances for Model-ID: ${modelId}. Error: ${message}`);
65
90
  }
66
91
  }
92
+ node.log(`Successfully deleted ${sumSuccessful} process instances and ${sumFailed} failed to delete process instances for Model-ID: ${modelId}.`);
93
+
94
+
67
95
  node.send(msg);
68
96
  } catch (queryError) {
69
- node.error(`Failed to query process instances: ${queryError.message}`);
97
+ node.error(`Failed to query process instances for Model-ID: ${modelId}. Error: ${queryError.message}`);
70
98
  }
71
99
  });
72
100
  }