bpmn-elements 8.1.0 → 8.2.0
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/CHANGELOG.md +6 -0
- package/dist/src/Context.js +8 -2
- package/dist/src/ExtensionsMapper.js +40 -40
- package/dist/src/activity/Activity.js +25 -53
- package/dist/src/io/BpmnIO.js +8 -0
- package/dist/src/io/InputOutputSpecification.js +22 -8
- package/dist/src/io/Properties.js +10 -9
- package/dist/src/tasks/ServiceTask.js +1 -5
- package/package.json +4 -4
- package/src/Context.js +7 -2
- package/src/ExtensionsMapper.js +35 -35
- package/src/activity/Activity.js +22 -51
- package/src/io/BpmnIO.js +7 -0
- package/src/io/EnvironmentDataObject.js +1 -0
- package/src/io/InputOutputSpecification.js +18 -6
- package/src/io/Properties.js +9 -11
- package/src/tasks/ServiceTask.js +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
# 8.2.0
|
|
5
|
+
|
|
6
|
+
- fix resume when activity has formatting status, extensions were not re-activated
|
|
7
|
+
- fix InputOutputSpecification output now passed as dataOutput instead of dataInput, as it should
|
|
8
|
+
- refactor Extensions loading, bpmn io is now pushed to the end of the extensions list
|
|
9
|
+
|
|
4
10
|
# 8.1.0
|
|
5
11
|
|
|
6
12
|
- support non-interrupting BoundaryEvent with ISO8601 repeating interval timeCycle
|
package/dist/src/Context.js
CHANGED
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = Context;
|
|
7
7
|
|
|
8
|
+
var _BpmnIO = _interopRequireDefault(require("./io/BpmnIO"));
|
|
9
|
+
|
|
8
10
|
var _Environment = _interopRequireDefault(require("./Environment"));
|
|
9
11
|
|
|
10
12
|
var _ExtensionsMapper = _interopRequireDefault(require("./ExtensionsMapper"));
|
|
@@ -31,7 +33,7 @@ function ContextInstance(definitionContext, environment) {
|
|
|
31
33
|
this.sid = sid;
|
|
32
34
|
this.definitionContext = definitionContext;
|
|
33
35
|
this.environment = environment;
|
|
34
|
-
this.extensionsMapper =
|
|
36
|
+
this.extensionsMapper = new _ExtensionsMapper.default(this);
|
|
35
37
|
this.refs = {
|
|
36
38
|
activityRefs: {},
|
|
37
39
|
associationRefs: [],
|
|
@@ -204,5 +206,9 @@ proto.getStartActivities = function getStartActivities(filterOptions, scopeId) {
|
|
|
204
206
|
};
|
|
205
207
|
|
|
206
208
|
proto.loadExtensions = function loadExtensions(activity) {
|
|
207
|
-
|
|
209
|
+
const io = new _BpmnIO.default(activity, this);
|
|
210
|
+
const extensions = this.extensionsMapper.get(activity);
|
|
211
|
+
if (io.hasIo) extensions.extensions.push(io);
|
|
212
|
+
if (!extensions.extensions.length) return;
|
|
213
|
+
return extensions;
|
|
208
214
|
};
|
|
@@ -4,50 +4,50 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = ExtensionsMapper;
|
|
7
|
+
const kActivated = Symbol.for('activated');
|
|
7
8
|
|
|
8
9
|
function ExtensionsMapper(context) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} = context.environment;
|
|
12
|
-
const extensions = getExtensions();
|
|
13
|
-
return {
|
|
14
|
-
get
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
function get(activity) {
|
|
18
|
-
const activityExtensions = extensions.reduce(applyExtension, []);
|
|
19
|
-
return {
|
|
20
|
-
activate,
|
|
21
|
-
deactivate
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function applyExtension(result, Extension) {
|
|
25
|
-
const extension = Extension(activity, context);
|
|
26
|
-
if (extension) result.push(extension);
|
|
27
|
-
return result;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function activate(message) {
|
|
31
|
-
for (const extension of activityExtensions) extension.activate(message);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function deactivate(message) {
|
|
35
|
-
for (const extension of activityExtensions) extension.deactivate(message);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
10
|
+
this.context = context;
|
|
11
|
+
}
|
|
38
12
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
13
|
+
ExtensionsMapper.prototype.get = function get(activity) {
|
|
14
|
+
return new Extensions(activity, this.context, this._getExtensions());
|
|
15
|
+
};
|
|
42
16
|
|
|
43
|
-
|
|
44
|
-
|
|
17
|
+
ExtensionsMapper.prototype._getExtensions = function getExtensions() {
|
|
18
|
+
let extensions;
|
|
19
|
+
if (!(extensions = this.context.environment.extensions)) return [];
|
|
20
|
+
return Object.values(extensions);
|
|
21
|
+
};
|
|
45
22
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
|
23
|
+
function Extensions(activity, context, extensions) {
|
|
24
|
+
const result = this.extensions = [];
|
|
50
25
|
|
|
51
|
-
|
|
26
|
+
for (const Extension of extensions) {
|
|
27
|
+
const extension = Extension(activity, context);
|
|
28
|
+
if (extension) result.push(extension);
|
|
52
29
|
}
|
|
53
|
-
|
|
30
|
+
|
|
31
|
+
this[kActivated] = false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Object.defineProperty(Extensions.prototype, 'count', {
|
|
35
|
+
get() {
|
|
36
|
+
return this.extensions.length;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
Extensions.prototype.activate = function activate(message) {
|
|
42
|
+
if (this[kActivated]) return;
|
|
43
|
+
this[kActivated] = true;
|
|
44
|
+
|
|
45
|
+
for (const extension of this.extensions) extension.activate(message);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
Extensions.prototype.deactivate = function deactivate(message) {
|
|
49
|
+
if (!this[kActivated]) return;
|
|
50
|
+
this[kActivated] = false;
|
|
51
|
+
|
|
52
|
+
for (const extension of this.extensions) extension.deactivate(message);
|
|
53
|
+
};
|
|
@@ -7,8 +7,6 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _ActivityExecution = _interopRequireDefault(require("./ActivityExecution"));
|
|
9
9
|
|
|
10
|
-
var _BpmnIO = _interopRequireDefault(require("../io/BpmnIO"));
|
|
11
|
-
|
|
12
10
|
var _shared = require("../shared");
|
|
13
11
|
|
|
14
12
|
var _Api = require("../Api");
|
|
@@ -24,7 +22,6 @@ var _Errors = require("../error/Errors");
|
|
|
24
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
23
|
|
|
26
24
|
const kActivityDef = Symbol.for('activityDefinition');
|
|
27
|
-
const kBpmnIo = Symbol.for('bpmnIo');
|
|
28
25
|
const kConsuming = Symbol.for('consuming');
|
|
29
26
|
const kCounters = Symbol.for('counters');
|
|
30
27
|
const kEventDefinitions = Symbol.for('eventDefinitions');
|
|
@@ -145,6 +142,7 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
145
142
|
}
|
|
146
143
|
|
|
147
144
|
this[kEventDefinitions] = eventDefinitions && eventDefinitions.map(ed => new ed.Behaviour(this, ed, this.context));
|
|
145
|
+
this[kExtensions] = context.loadExtensions(this);
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
const proto = Activity.prototype;
|
|
@@ -173,23 +171,20 @@ Object.defineProperty(proto, 'executionId', {
|
|
|
173
171
|
}
|
|
174
172
|
|
|
175
173
|
});
|
|
176
|
-
Object.defineProperty(proto, '
|
|
174
|
+
Object.defineProperty(proto, 'extensions', {
|
|
177
175
|
enumerable: true,
|
|
178
176
|
|
|
179
177
|
get() {
|
|
180
|
-
|
|
181
|
-
const bpmnIo = this[kBpmnIo] = new _BpmnIO.default(this, this.context);
|
|
182
|
-
return bpmnIo;
|
|
178
|
+
return this[kExtensions];
|
|
183
179
|
}
|
|
184
180
|
|
|
185
181
|
});
|
|
186
|
-
Object.defineProperty(proto, '
|
|
182
|
+
Object.defineProperty(proto, 'bpmnIo', {
|
|
187
183
|
enumerable: true,
|
|
188
184
|
|
|
189
185
|
get() {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return extensions;
|
|
186
|
+
const extensions = this[kExtensions];
|
|
187
|
+
return extensions && extensions.extensions.find(e => e.type === 'bpmnio');
|
|
193
188
|
}
|
|
194
189
|
|
|
195
190
|
});
|
|
@@ -485,10 +480,11 @@ proto._discardRun = function discardRun() {
|
|
|
485
480
|
|
|
486
481
|
this._deactivateRunConsumers();
|
|
487
482
|
|
|
488
|
-
|
|
483
|
+
const message = this[kStateMessage];
|
|
484
|
+
if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(message));
|
|
489
485
|
const broker = this.broker;
|
|
490
486
|
broker.getQueue('run-q').purge();
|
|
491
|
-
broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(
|
|
487
|
+
broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(message.content));
|
|
492
488
|
|
|
493
489
|
this._consumeRunQ();
|
|
494
490
|
};
|
|
@@ -720,13 +716,13 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
720
716
|
|
|
721
717
|
if (!isRedelivered) {
|
|
722
718
|
this[kExec].execution = null;
|
|
719
|
+
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
|
|
720
|
+
|
|
721
|
+
this._publishEvent('enter', content, {
|
|
722
|
+
correlationId
|
|
723
|
+
});
|
|
723
724
|
}
|
|
724
725
|
|
|
725
|
-
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message), this);
|
|
726
|
-
if (this.bpmnIo) this.bpmnIo.activate(message);
|
|
727
|
-
if (!isRedelivered) this._publishEvent('enter', content, {
|
|
728
|
-
correlationId
|
|
729
|
-
});
|
|
730
726
|
break;
|
|
731
727
|
}
|
|
732
728
|
|
|
@@ -735,8 +731,7 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
735
731
|
this.logger.debug(`<${id}> discard`, isRedelivered ? 'redelivered' : '');
|
|
736
732
|
this.status = 'discard';
|
|
737
733
|
this[kExec].execution = null;
|
|
738
|
-
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message)
|
|
739
|
-
if (this.bpmnIo) this.bpmnIo.activate(message);
|
|
734
|
+
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
|
|
740
735
|
|
|
741
736
|
if (!isRedelivered) {
|
|
742
737
|
this.broker.publish('run', 'run.discarded', content, {
|
|
@@ -781,28 +776,20 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
781
776
|
{
|
|
782
777
|
this.status = 'executing';
|
|
783
778
|
this[kExecuteMessage] = message;
|
|
779
|
+
const exec = this[kExec];
|
|
780
|
+
if (isRedelivered && this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
|
|
781
|
+
if (!exec.execution) exec.execution = new _ActivityExecution.default(this, this.context);
|
|
784
782
|
this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {
|
|
785
783
|
exclusive: true,
|
|
786
784
|
consumerTag: '_activity-execution'
|
|
787
785
|
});
|
|
788
|
-
const exec = this[kExec];
|
|
789
|
-
if (!exec.execution) exec.execution = new _ActivityExecution.default(this, this.context);
|
|
790
|
-
|
|
791
|
-
if (isRedelivered) {
|
|
792
|
-
return this._resumeExtensions(message, (err, formattedContent) => {
|
|
793
|
-
if (err) return this.emitFatal(err, message.content);
|
|
794
|
-
if (formattedContent) message.content = formattedContent;
|
|
795
|
-
this.status = 'executing';
|
|
796
|
-
return exec.execution.execute(message);
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
|
|
800
786
|
return exec.execution.execute(message);
|
|
801
787
|
}
|
|
802
788
|
|
|
803
789
|
case 'run.end':
|
|
804
790
|
{
|
|
805
|
-
|
|
791
|
+
this.logger.debug(`<${id}> end`, isRedelivered ? 'redelivered' : '');
|
|
792
|
+
if (isRedelivered) break;
|
|
806
793
|
this[kCounters].taken++;
|
|
807
794
|
this.status = 'end';
|
|
808
795
|
return this._doRunLeave(message, false, () => {
|
|
@@ -860,8 +847,7 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
860
847
|
case 'run.leave':
|
|
861
848
|
{
|
|
862
849
|
this.status = undefined;
|
|
863
|
-
if (this.
|
|
864
|
-
if (this.extensions) this.extensions.deactivate(message);
|
|
850
|
+
if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(message));
|
|
865
851
|
|
|
866
852
|
if (!isRedelivered) {
|
|
867
853
|
this.broker.publish('run', 'run.next', content, {
|
|
@@ -1044,9 +1030,8 @@ proto._doRunOutbound = function doRunOutbound(outboundList, content, discardSequ
|
|
|
1044
1030
|
proto._onResumeMessage = function onResumeMessage(message) {
|
|
1045
1031
|
message.ack();
|
|
1046
1032
|
const stateMessage = this[kStateMessage];
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
} = stateMessage;
|
|
1033
|
+
const fields = stateMessage.fields;
|
|
1034
|
+
if (!fields.redelivered) return;
|
|
1050
1035
|
|
|
1051
1036
|
switch (fields.routingKey) {
|
|
1052
1037
|
case 'run.enter':
|
|
@@ -1060,7 +1045,7 @@ proto._onResumeMessage = function onResumeMessage(message) {
|
|
|
1060
1045
|
return;
|
|
1061
1046
|
}
|
|
1062
1047
|
|
|
1063
|
-
if (
|
|
1048
|
+
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(stateMessage));
|
|
1064
1049
|
this.logger.debug(`<${this.id}> resume from ${message.content.status}`);
|
|
1065
1050
|
return this.broker.publish('run', fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
|
|
1066
1051
|
};
|
|
@@ -1087,7 +1072,7 @@ proto._onStop = function onStop(message) {
|
|
|
1087
1072
|
broker.cancel('_format-consumer');
|
|
1088
1073
|
|
|
1089
1074
|
if (running) {
|
|
1090
|
-
if (this.extensions) this.extensions.deactivate(message
|
|
1075
|
+
if (this.extensions) this.extensions.deactivate(message ? (0, _messageHelper.cloneMessage)(message) : this._createMessage());
|
|
1091
1076
|
|
|
1092
1077
|
this._publishEvent('stop', this._createMessage());
|
|
1093
1078
|
}
|
|
@@ -1153,19 +1138,6 @@ proto._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId
|
|
|
1153
1138
|
return this[kFlows].outboundSequenceFlows.find(flow => flow.id === flowId);
|
|
1154
1139
|
};
|
|
1155
1140
|
|
|
1156
|
-
proto._resumeExtensions = function resumeExtensions(message, callback) {
|
|
1157
|
-
const extensions = this.extensions,
|
|
1158
|
-
bpmnIo = this.bpmnIo;
|
|
1159
|
-
if (!extensions && !bpmnIo) return callback();
|
|
1160
|
-
if (extensions) extensions.activate((0, _messageHelper.cloneMessage)(message), this);
|
|
1161
|
-
if (bpmnIo) bpmnIo.activate((0, _messageHelper.cloneMessage)(message), this);
|
|
1162
|
-
this.status = 'formatting';
|
|
1163
|
-
return this.formatter.format(message, (err, formattedContent, formatted) => {
|
|
1164
|
-
if (err) return callback(err);
|
|
1165
|
-
return callback(null, formatted && formattedContent);
|
|
1166
|
-
});
|
|
1167
|
-
};
|
|
1168
|
-
|
|
1169
1141
|
proto._deactivateRunConsumers = function _deactivateRunConsumers() {
|
|
1170
1142
|
const broker = this.broker;
|
|
1171
1143
|
broker.cancel('_activity-api');
|
package/dist/src/io/BpmnIO.js
CHANGED
|
@@ -8,6 +8,7 @@ exports.default = BpmnIO;
|
|
|
8
8
|
function BpmnIO(activity, context) {
|
|
9
9
|
this.activity = activity;
|
|
10
10
|
this.context = context;
|
|
11
|
+
this.type = 'bpmnio';
|
|
11
12
|
const {
|
|
12
13
|
ioSpecification: ioSpecificationDef,
|
|
13
14
|
properties: propertiesDef
|
|
@@ -16,6 +17,13 @@ function BpmnIO(activity, context) {
|
|
|
16
17
|
this.properties = propertiesDef && new propertiesDef.Behaviour(activity, propertiesDef, context);
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
Object.defineProperty(BpmnIO.prototype, 'hasIo', {
|
|
21
|
+
get() {
|
|
22
|
+
return this.specification || this.properties;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
});
|
|
26
|
+
|
|
19
27
|
BpmnIO.prototype.activate = function activate(message) {
|
|
20
28
|
const properties = this.properties,
|
|
21
29
|
specification = this.specification;
|
|
@@ -29,8 +29,17 @@ function IoSpecification(activity, ioSpecificationDef, context) {
|
|
|
29
29
|
|
|
30
30
|
const proto = IoSpecification.prototype;
|
|
31
31
|
|
|
32
|
-
proto.activate = function activate() {
|
|
32
|
+
proto.activate = function activate(message) {
|
|
33
33
|
if (this[kConsuming]) return;
|
|
34
|
+
|
|
35
|
+
if (message && message.fields.redelivered && message.fields.routingKey === 'run.start') {
|
|
36
|
+
this._onFormatEnter();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (message && message.fields.redelivered && message.fields.routingKey === 'run.end') {
|
|
40
|
+
this._onFormatComplete(message);
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
this[kConsuming] = this.broker.subscribeTmp('event', 'activity.#', this._onActivityEvent.bind(this), {
|
|
35
44
|
noAck: true
|
|
36
45
|
});
|
|
@@ -177,10 +186,11 @@ proto._onFormatComplete = function formatOnComplete(message) {
|
|
|
177
186
|
const endRoutingKey = `run.onend.${safeType}.end`;
|
|
178
187
|
broker.publish('format', `${startRoutingKey}.begin`, {
|
|
179
188
|
endRoutingKey,
|
|
180
|
-
ioSpecification: {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
189
|
+
ioSpecification: { ...(messageInputs && {
|
|
190
|
+
dataInputs: messageInputs.map(input => {
|
|
191
|
+
return { ...input
|
|
192
|
+
};
|
|
193
|
+
})
|
|
184
194
|
}),
|
|
185
195
|
dataOutputs: this._getDataOutputs(dataOutputs)
|
|
186
196
|
}
|
|
@@ -189,9 +199,13 @@ proto._onFormatComplete = function formatOnComplete(message) {
|
|
|
189
199
|
for (const response of responses) sources[response.index].value = response.value;
|
|
190
200
|
|
|
191
201
|
broker.publish('format', endRoutingKey, {
|
|
192
|
-
ioSpecification: {
|
|
193
|
-
|
|
194
|
-
|
|
202
|
+
ioSpecification: { ...(messageInputs && {
|
|
203
|
+
dataInputs: messageInputs.map(input => {
|
|
204
|
+
return { ...input
|
|
205
|
+
};
|
|
206
|
+
})
|
|
207
|
+
}),
|
|
208
|
+
dataOutputs: sources
|
|
195
209
|
}
|
|
196
210
|
});
|
|
197
211
|
});
|
|
@@ -87,6 +87,10 @@ const proto = Properties.prototype;
|
|
|
87
87
|
proto.activate = function activate(message) {
|
|
88
88
|
if (this[kConsuming]) return;
|
|
89
89
|
|
|
90
|
+
if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
|
|
91
|
+
this._onActivityEvent('activity.enter', message);
|
|
92
|
+
}
|
|
93
|
+
|
|
90
94
|
if (message.fields.redelivered && message.content.properties) {
|
|
91
95
|
this._onActivityEvent('activity.extension.resume', message);
|
|
92
96
|
}
|
|
@@ -101,16 +105,13 @@ proto.deactivate = function deactivate() {
|
|
|
101
105
|
};
|
|
102
106
|
|
|
103
107
|
proto._onActivityEvent = function onActivityEvent(routingKey, message) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (routingKey === 'activity.extension.resume') {
|
|
109
|
-
return this._formatOnEnter(message);
|
|
110
|
-
}
|
|
108
|
+
switch (routingKey) {
|
|
109
|
+
case 'activity.enter':
|
|
110
|
+
case 'activity.extension.resume':
|
|
111
|
+
return this._formatOnEnter(message);
|
|
111
112
|
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
case 'activity.execution.completed':
|
|
114
|
+
return this._formatOnComplete(message);
|
|
114
115
|
}
|
|
115
116
|
};
|
|
116
117
|
|
|
@@ -70,11 +70,7 @@ proto.execute = function execute(executeMessage) {
|
|
|
70
70
|
|
|
71
71
|
proto.getService = function getService(message) {
|
|
72
72
|
let Service = this.activity.behaviour.Service;
|
|
73
|
-
|
|
74
|
-
if (!Service) {
|
|
75
|
-
Service = this.environment.settings.enableDummyService ? DummyService : null;
|
|
76
|
-
}
|
|
77
|
-
|
|
73
|
+
if (!Service && this.environment.settings.enableDummyService) Service = DummyService;
|
|
78
74
|
return Service && new Service(this.activity, (0, _messageHelper.cloneMessage)(message));
|
|
79
75
|
};
|
|
80
76
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bpmn-elements",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"description": "Executable workflow elements based on BPMN 2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "index.js",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
],
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@aircall/expression-parser": "^1.0.4",
|
|
49
|
-
"@babel/cli": "^7.
|
|
50
|
-
"@babel/core": "^7.
|
|
51
|
-
"@babel/preset-env": "^7.
|
|
49
|
+
"@babel/cli": "^7.19.3",
|
|
50
|
+
"@babel/core": "^7.19.3",
|
|
51
|
+
"@babel/preset-env": "^7.19.3",
|
|
52
52
|
"@babel/register": "^7.18.6",
|
|
53
53
|
"bpmn-moddle": "^7.1.2",
|
|
54
54
|
"camunda-bpmn-moddle": "^6.1.2",
|
package/src/Context.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import BpmnIO from './io/BpmnIO';
|
|
1
2
|
import Environment from './Environment';
|
|
2
3
|
import ExtensionsMapper from './ExtensionsMapper';
|
|
3
4
|
import {getUniqueId} from './shared';
|
|
@@ -16,7 +17,7 @@ function ContextInstance(definitionContext, environment) {
|
|
|
16
17
|
this.sid = sid;
|
|
17
18
|
this.definitionContext = definitionContext;
|
|
18
19
|
this.environment = environment;
|
|
19
|
-
this.extensionsMapper = ExtensionsMapper(this);
|
|
20
|
+
this.extensionsMapper = new ExtensionsMapper(this);
|
|
20
21
|
this.refs = {
|
|
21
22
|
activityRefs: {},
|
|
22
23
|
associationRefs: [],
|
|
@@ -196,6 +197,10 @@ proto.getStartActivities = function getStartActivities(filterOptions, scopeId) {
|
|
|
196
197
|
};
|
|
197
198
|
|
|
198
199
|
proto.loadExtensions = function loadExtensions(activity) {
|
|
199
|
-
|
|
200
|
+
const io = new BpmnIO(activity, this);
|
|
201
|
+
const extensions = this.extensionsMapper.get(activity);
|
|
202
|
+
if (io.hasIo) extensions.extensions.push(io);
|
|
203
|
+
if (!extensions.extensions.length) return;
|
|
204
|
+
return extensions;
|
|
200
205
|
};
|
|
201
206
|
|
package/src/ExtensionsMapper.js
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
const {extensions: envExtensions} = context.environment;
|
|
3
|
-
const extensions = getExtensions();
|
|
1
|
+
const kActivated = Symbol.for('activated');
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export default function ExtensionsMapper(context) {
|
|
4
|
+
this.context = context;
|
|
5
|
+
}
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
activate,
|
|
13
|
-
deactivate,
|
|
14
|
-
};
|
|
7
|
+
ExtensionsMapper.prototype.get = function get(activity) {
|
|
8
|
+
return new Extensions(activity, this.context, this._getExtensions());
|
|
9
|
+
};
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
ExtensionsMapper.prototype._getExtensions = function getExtensions() {
|
|
12
|
+
let extensions;
|
|
13
|
+
if (!(extensions = this.context.environment.extensions)) return [];
|
|
14
|
+
return Object.values(extensions);
|
|
15
|
+
};
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
17
|
+
function Extensions(activity, context, extensions) {
|
|
18
|
+
const result = this.extensions = [];
|
|
19
|
+
for (const Extension of extensions) {
|
|
20
|
+
const extension = Extension(activity, context);
|
|
21
|
+
if (extension) result.push(extension);
|
|
28
22
|
}
|
|
23
|
+
this[kActivated] = false;
|
|
24
|
+
}
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
Object.defineProperty(Extensions.prototype, 'count', {
|
|
27
|
+
get() {
|
|
28
|
+
return this.extensions.length;
|
|
29
|
+
},
|
|
30
|
+
});
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
Extensions.prototype.activate = function activate(message) {
|
|
33
|
+
if (this[kActivated]) return;
|
|
34
|
+
this[kActivated] = true;
|
|
35
|
+
for (const extension of this.extensions) extension.activate(message);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Extensions.prototype.deactivate = function deactivate(message) {
|
|
39
|
+
if (!this[kActivated]) return;
|
|
40
|
+
this[kActivated] = false;
|
|
41
|
+
for (const extension of this.extensions) extension.deactivate(message);
|
|
42
|
+
};
|
package/src/activity/Activity.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import ActivityExecution from './ActivityExecution';
|
|
2
|
-
import BpmnIO from '../io/BpmnIO';
|
|
3
2
|
import {brokerSafeId, getUniqueId} from '../shared';
|
|
4
3
|
import {ActivityApi} from '../Api';
|
|
5
4
|
import {ActivityBroker} from '../EventBroker';
|
|
@@ -8,7 +7,6 @@ import {cloneContent, cloneParent, cloneMessage} from '../messageHelper';
|
|
|
8
7
|
import {makeErrorFromMessage, ActivityError} from '../error/Errors';
|
|
9
8
|
|
|
10
9
|
const kActivityDef = Symbol.for('activityDefinition');
|
|
11
|
-
const kBpmnIo = Symbol.for('bpmnIo');
|
|
12
10
|
const kConsuming = Symbol.for('consuming');
|
|
13
11
|
const kCounters = Symbol.for('counters');
|
|
14
12
|
const kEventDefinitions = Symbol.for('eventDefinitions');
|
|
@@ -105,6 +103,7 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
this[kEventDefinitions] = eventDefinitions && eventDefinitions.map((ed) => new ed.Behaviour(this, ed, this.context));
|
|
106
|
+
this[kExtensions] = context.loadExtensions(this);
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
const proto = Activity.prototype;
|
|
@@ -130,21 +129,18 @@ Object.defineProperty(proto, 'executionId', {
|
|
|
130
129
|
},
|
|
131
130
|
});
|
|
132
131
|
|
|
133
|
-
Object.defineProperty(proto, '
|
|
132
|
+
Object.defineProperty(proto, 'extensions', {
|
|
134
133
|
enumerable: true,
|
|
135
134
|
get() {
|
|
136
|
-
|
|
137
|
-
const bpmnIo = this[kBpmnIo] = new BpmnIO(this, this.context);
|
|
138
|
-
return bpmnIo;
|
|
135
|
+
return this[kExtensions];
|
|
139
136
|
},
|
|
140
137
|
});
|
|
141
138
|
|
|
142
|
-
Object.defineProperty(proto, '
|
|
139
|
+
Object.defineProperty(proto, 'bpmnIo', {
|
|
143
140
|
enumerable: true,
|
|
144
141
|
get() {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return extensions;
|
|
142
|
+
const extensions = this[kExtensions];
|
|
143
|
+
return extensions && extensions.extensions.find(e => e.type === 'bpmnio');
|
|
148
144
|
},
|
|
149
145
|
});
|
|
150
146
|
|
|
@@ -408,10 +404,12 @@ proto._discardRun = function discardRun() {
|
|
|
408
404
|
}
|
|
409
405
|
|
|
410
406
|
this._deactivateRunConsumers();
|
|
411
|
-
|
|
407
|
+
|
|
408
|
+
const message = this[kStateMessage];
|
|
409
|
+
if (this.extensions) this.extensions.deactivate(cloneMessage(message));
|
|
412
410
|
const broker = this.broker;
|
|
413
411
|
broker.getQueue('run-q').purge();
|
|
414
|
-
broker.publish('run', 'run.discard', cloneContent(
|
|
412
|
+
broker.publish('run', 'run.discard', cloneContent(message.content));
|
|
415
413
|
this._consumeRunQ();
|
|
416
414
|
};
|
|
417
415
|
|
|
@@ -601,12 +599,9 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
601
599
|
this.status = 'entered';
|
|
602
600
|
if (!isRedelivered) {
|
|
603
601
|
this[kExec].execution = null;
|
|
602
|
+
if (this.extensions) this.extensions.activate(cloneMessage(message));
|
|
603
|
+
this._publishEvent('enter', content, {correlationId});
|
|
604
604
|
}
|
|
605
|
-
|
|
606
|
-
if (this.extensions) this.extensions.activate(cloneMessage(message), this);
|
|
607
|
-
if (this.bpmnIo) this.bpmnIo.activate(message);
|
|
608
|
-
|
|
609
|
-
if (!isRedelivered) this._publishEvent('enter', content, {correlationId});
|
|
610
605
|
break;
|
|
611
606
|
}
|
|
612
607
|
case 'run.discard': {
|
|
@@ -615,8 +610,7 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
615
610
|
this.status = 'discard';
|
|
616
611
|
this[kExec].execution = null;
|
|
617
612
|
|
|
618
|
-
if (this.extensions) this.extensions.activate(cloneMessage(message)
|
|
619
|
-
if (this.bpmnIo) this.bpmnIo.activate(message);
|
|
613
|
+
if (this.extensions) this.extensions.activate(cloneMessage(message));
|
|
620
614
|
|
|
621
615
|
if (!isRedelivered) {
|
|
622
616
|
this.broker.publish('run', 'run.discarded', content, {correlationId});
|
|
@@ -631,7 +625,6 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
631
625
|
this.broker.publish('run', 'run.execute', content, {correlationId});
|
|
632
626
|
this._publishEvent('start', content, {correlationId});
|
|
633
627
|
}
|
|
634
|
-
|
|
635
628
|
break;
|
|
636
629
|
}
|
|
637
630
|
case 'run.execute.passthrough': {
|
|
@@ -645,23 +638,15 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
645
638
|
this.status = 'executing';
|
|
646
639
|
this[kExecuteMessage] = message;
|
|
647
640
|
|
|
648
|
-
this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {exclusive: true, consumerTag: '_activity-execution'});
|
|
649
641
|
const exec = this[kExec];
|
|
642
|
+
if (isRedelivered && this.extensions) this.extensions.activate(cloneMessage(message));
|
|
650
643
|
if (!exec.execution) exec.execution = new ActivityExecution(this, this.context);
|
|
651
|
-
|
|
652
|
-
if (isRedelivered) {
|
|
653
|
-
return this._resumeExtensions(message, (err, formattedContent) => {
|
|
654
|
-
if (err) return this.emitFatal(err, message.content);
|
|
655
|
-
if (formattedContent) message.content = formattedContent;
|
|
656
|
-
this.status = 'executing';
|
|
657
|
-
return exec.execution.execute(message);
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
|
|
644
|
+
this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {exclusive: true, consumerTag: '_activity-execution'});
|
|
661
645
|
return exec.execution.execute(message);
|
|
662
646
|
}
|
|
663
647
|
case 'run.end': {
|
|
664
|
-
|
|
648
|
+
this.logger.debug(`<${id}> end`, isRedelivered ? 'redelivered' : '');
|
|
649
|
+
if (isRedelivered) break;
|
|
665
650
|
|
|
666
651
|
this[kCounters].taken++;
|
|
667
652
|
|
|
@@ -707,8 +692,7 @@ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
|
707
692
|
case 'run.leave': {
|
|
708
693
|
this.status = undefined;
|
|
709
694
|
|
|
710
|
-
if (this.
|
|
711
|
-
if (this.extensions) this.extensions.deactivate(message);
|
|
695
|
+
if (this.extensions) this.extensions.deactivate(cloneMessage(message));
|
|
712
696
|
|
|
713
697
|
if (!isRedelivered) {
|
|
714
698
|
this.broker.publish('run', 'run.next', content, {persistent: false});
|
|
@@ -844,7 +828,8 @@ proto._onResumeMessage = function onResumeMessage(message) {
|
|
|
844
828
|
message.ack();
|
|
845
829
|
|
|
846
830
|
const stateMessage = this[kStateMessage];
|
|
847
|
-
const
|
|
831
|
+
const fields = stateMessage.fields;
|
|
832
|
+
if (!fields.redelivered) return;
|
|
848
833
|
|
|
849
834
|
switch (fields.routingKey) {
|
|
850
835
|
case 'run.enter':
|
|
@@ -857,7 +842,7 @@ proto._onResumeMessage = function onResumeMessage(message) {
|
|
|
857
842
|
return;
|
|
858
843
|
}
|
|
859
844
|
|
|
860
|
-
if (
|
|
845
|
+
if (this.extensions) this.extensions.activate(cloneMessage(stateMessage));
|
|
861
846
|
|
|
862
847
|
this.logger.debug(`<${this.id}> resume from ${message.content.status}`);
|
|
863
848
|
|
|
@@ -887,7 +872,7 @@ proto._onStop = function onStop(message) {
|
|
|
887
872
|
broker.cancel('_format-consumer');
|
|
888
873
|
|
|
889
874
|
if (running) {
|
|
890
|
-
if (this.extensions) this.extensions.deactivate(message
|
|
875
|
+
if (this.extensions) this.extensions.deactivate(message ? cloneMessage(message) : this._createMessage());
|
|
891
876
|
this._publishEvent('stop', this._createMessage());
|
|
892
877
|
}
|
|
893
878
|
};
|
|
@@ -936,20 +921,6 @@ proto._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId
|
|
|
936
921
|
return this[kFlows].outboundSequenceFlows.find((flow) => flow.id === flowId);
|
|
937
922
|
};
|
|
938
923
|
|
|
939
|
-
proto._resumeExtensions = function resumeExtensions(message, callback) {
|
|
940
|
-
const extensions = this.extensions, bpmnIo = this.bpmnIo;
|
|
941
|
-
if (!extensions && !bpmnIo) return callback();
|
|
942
|
-
|
|
943
|
-
if (extensions) extensions.activate(cloneMessage(message), this);
|
|
944
|
-
if (bpmnIo) bpmnIo.activate(cloneMessage(message), this);
|
|
945
|
-
|
|
946
|
-
this.status = 'formatting';
|
|
947
|
-
return this.formatter.format(message, (err, formattedContent, formatted) => {
|
|
948
|
-
if (err) return callback(err);
|
|
949
|
-
return callback(null, formatted && formattedContent);
|
|
950
|
-
});
|
|
951
|
-
};
|
|
952
|
-
|
|
953
924
|
proto._deactivateRunConsumers = function _deactivateRunConsumers() {
|
|
954
925
|
const broker = this.broker;
|
|
955
926
|
broker.cancel('_activity-api');
|
package/src/io/BpmnIO.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default function BpmnIO(activity, context) {
|
|
2
2
|
this.activity = activity;
|
|
3
3
|
this.context = context;
|
|
4
|
+
this.type = 'bpmnio';
|
|
4
5
|
|
|
5
6
|
const {
|
|
6
7
|
ioSpecification: ioSpecificationDef,
|
|
@@ -11,6 +12,12 @@ export default function BpmnIO(activity, context) {
|
|
|
11
12
|
this.properties = propertiesDef && new propertiesDef.Behaviour(activity, propertiesDef, context);
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
Object.defineProperty(BpmnIO.prototype, 'hasIo', {
|
|
16
|
+
get() {
|
|
17
|
+
return this.specification || this.properties;
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
14
21
|
BpmnIO.prototype.activate = function activate(message) {
|
|
15
22
|
const properties = this.properties, specification = this.specification;
|
|
16
23
|
if (properties) properties.activate(message);
|
|
@@ -9,6 +9,7 @@ export default function EnvironmentDataObject(dataObjectDef, {environment}) {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
EnvironmentDataObject.prototype.read = function read(broker, exchange, routingKeyPrefix, messageProperties) {
|
|
12
|
+
|
|
12
13
|
const environment = this.environment;
|
|
13
14
|
const value = environment.variables._data && environment.variables._data[this.id];
|
|
14
15
|
const content = this._createContent(value);
|
|
@@ -15,8 +15,14 @@ export default function IoSpecification(activity, ioSpecificationDef, context) {
|
|
|
15
15
|
|
|
16
16
|
const proto = IoSpecification.prototype;
|
|
17
17
|
|
|
18
|
-
proto.activate = function activate() {
|
|
18
|
+
proto.activate = function activate(message) {
|
|
19
19
|
if (this[kConsuming]) return;
|
|
20
|
+
if (message && message.fields.redelivered && message.fields.routingKey === 'run.start') {
|
|
21
|
+
this._onFormatEnter();
|
|
22
|
+
}
|
|
23
|
+
if (message && message.fields.redelivered && message.fields.routingKey === 'run.end') {
|
|
24
|
+
this._onFormatComplete(message);
|
|
25
|
+
}
|
|
20
26
|
this[kConsuming] = this.broker.subscribeTmp('event', 'activity.#', this._onActivityEvent.bind(this), {noAck: true});
|
|
21
27
|
};
|
|
22
28
|
|
|
@@ -107,6 +113,7 @@ proto._onFormatComplete = function formatOnComplete(message) {
|
|
|
107
113
|
const broker = this.broker;
|
|
108
114
|
const context = this.context;
|
|
109
115
|
|
|
116
|
+
|
|
110
117
|
const {dataObjects, sources} = dataOutputs.reduce((result, ioSource, index) => {
|
|
111
118
|
const {value} = messageOutputs.find((output) => output.id === ioSource.id) || {};
|
|
112
119
|
const source = {
|
|
@@ -117,7 +124,6 @@ proto._onFormatComplete = function formatOnComplete(message) {
|
|
|
117
124
|
};
|
|
118
125
|
result.sources.push(source);
|
|
119
126
|
|
|
120
|
-
|
|
121
127
|
const dataObjectId = getPropertyValue(ioSource, 'behaviour.association.target.dataObject.id');
|
|
122
128
|
if (!dataObjectId) return result;
|
|
123
129
|
const dataObject = context.getDataObjectById(dataObjectId);
|
|
@@ -143,8 +149,10 @@ proto._onFormatComplete = function formatOnComplete(message) {
|
|
|
143
149
|
broker.publish('format', `${startRoutingKey}.begin`, {
|
|
144
150
|
endRoutingKey,
|
|
145
151
|
ioSpecification: {
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
...(messageInputs && {
|
|
153
|
+
dataInputs: messageInputs.map((input) => {
|
|
154
|
+
return {...input};
|
|
155
|
+
}),
|
|
148
156
|
}),
|
|
149
157
|
dataOutputs: this._getDataOutputs(dataOutputs),
|
|
150
158
|
},
|
|
@@ -155,8 +163,12 @@ proto._onFormatComplete = function formatOnComplete(message) {
|
|
|
155
163
|
|
|
156
164
|
broker.publish('format', endRoutingKey, {
|
|
157
165
|
ioSpecification: {
|
|
158
|
-
|
|
159
|
-
|
|
166
|
+
...(messageInputs && {
|
|
167
|
+
dataInputs: messageInputs.map((input) => {
|
|
168
|
+
return {...input};
|
|
169
|
+
}),
|
|
170
|
+
}),
|
|
171
|
+
dataOutputs: sources,
|
|
160
172
|
},
|
|
161
173
|
});
|
|
162
174
|
});
|
package/src/io/Properties.js
CHANGED
|
@@ -13,7 +13,6 @@ export default function Properties(activity, propertiesDef, context) {
|
|
|
13
13
|
dataOutputObjects: [],
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
for (const {id, ...def} of propertiesDef.values) {
|
|
18
17
|
const source = {
|
|
19
18
|
id,
|
|
@@ -62,6 +61,9 @@ const proto = Properties.prototype;
|
|
|
62
61
|
|
|
63
62
|
proto.activate = function activate(message) {
|
|
64
63
|
if (this[kConsuming]) return;
|
|
64
|
+
if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
|
|
65
|
+
this._onActivityEvent('activity.enter', message);
|
|
66
|
+
}
|
|
65
67
|
|
|
66
68
|
if (message.fields.redelivered && message.content.properties) {
|
|
67
69
|
this._onActivityEvent('activity.extension.resume', message);
|
|
@@ -75,16 +77,12 @@ proto.deactivate = function deactivate() {
|
|
|
75
77
|
};
|
|
76
78
|
|
|
77
79
|
proto._onActivityEvent = function onActivityEvent(routingKey, message) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (routingKey === 'activity.execution.completed') {
|
|
87
|
-
return this._formatOnComplete(message);
|
|
80
|
+
switch (routingKey) {
|
|
81
|
+
case 'activity.enter':
|
|
82
|
+
case 'activity.extension.resume':
|
|
83
|
+
return this._formatOnEnter(message);
|
|
84
|
+
case 'activity.execution.completed':
|
|
85
|
+
return this._formatOnComplete(message);
|
|
88
86
|
}
|
|
89
87
|
};
|
|
90
88
|
|
package/src/tasks/ServiceTask.js
CHANGED
|
@@ -46,9 +46,7 @@ proto.execute = function execute(executeMessage) {
|
|
|
46
46
|
|
|
47
47
|
proto.getService = function getService(message) {
|
|
48
48
|
let Service = this.activity.behaviour.Service;
|
|
49
|
-
if (!Service)
|
|
50
|
-
Service = this.environment.settings.enableDummyService ? DummyService : null;
|
|
51
|
-
}
|
|
49
|
+
if (!Service && this.environment.settings.enableDummyService) Service = DummyService;
|
|
52
50
|
return Service && new Service(this.activity, cloneMessage(message));
|
|
53
51
|
};
|
|
54
52
|
|