UNPKG

@5minds/processcube_engine

Version:

The ProcessCube Engine. Stores and executes BPMNs.

210 lines • 11.5 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IntermediateMessageCatchEventHandler = void 0; const inversify_1 = require("inversify"); const processcube_engine_sdk_1 = require("@5minds/processcube_engine_sdk"); const index_1 = require("../../../Contracts/index"); const AbortablePromise_1 = require("../../../Tools/AbortablePromise"); const index_2 = require("../../../Tools/DatabaseAdaptersSequelize/index"); const EventMiddlewareHandler_1 = require("../../../Tools/EventMiddlewareHandler"); const MessageEventService_1 = require("../../MessageEventService"); const ProcessInstance_1 = require("../../ProcessInstance"); const FlowNodeHandlerFactory_1 = require("../FlowNodeHandlerFactory"); const EventHandler_1 = require("./EventHandler"); let IntermediateMessageCatchEventHandler = class IntermediateMessageCatchEventHandler extends EventHandler_1.EventHandler { messageEventService; onMessageSubscriptionId; acknowledgeEventReceivedId; triggerValue; constructor(eventMiddlewareHandler, flowNodeHandlerFactory, flowNodeInstanceDatabaseAdapter, messageCatchEventModel, processInstance, messageEventService) { super(eventMiddlewareHandler, flowNodeHandlerFactory, flowNodeInstanceDatabaseAdapter, messageCatchEventModel, processInstance, 'message_catch_event_handler'); this.messageEventService = messageEventService; } get messageCatchEvent() { return this.flowNode; } async persistOnSuspend() { this.abortSignal.signal.throwIfAborted(); await super.persistOnSuspend(undefined, { type: index_1.FlowNodeInstanceDataTypes.catchEvent, eventName: this.messageCatchEvent.messageEventDefinition.name, triggerValue: this.triggerValue, }); this.publishIntermediateCatchEventReachedNotification(); } async persistOnExit() { await super.persistOnExit({ type: index_1.FlowNodeInstanceDataTypes.catchEvent, eventName: this.messageCatchEvent.messageEventDefinition.name, triggerValue: this.triggerValue, triggeredByFlowNodeInstanceId: this.triggeredByFlowNodeInstanceId, }); this.publishIntermediateCatchEventFinishedNotification(); } async persistOnError(error) { await super.persistOnError(error); this.publishIntermediateCatchEventFinishedNotification(); } async persistOnTerminate() { await super.persistOnTerminate(); this.publishIntermediateCatchEventFinishedNotification(); } async afterExecute() { await super.afterExecute(); this.messageEventService.acknowledge(this.acknowledgeEventReceivedId); this.messageEventService.unsubscribe(this.onMessageSubscriptionId); } async startExecution(executionCanceledCallback) { this.abortSignal.signal.throwIfAborted(); this.logger.debug(`Executing MessageCatchEvent instance.`); return this.executeHandler(executionCanceledCallback); } async executeHandler(executionCanceledCallback) { this.abortSignal.signal.throwIfAborted(); return new AbortablePromise_1.AbortablePromise(async (resolve, reject, onCancel) => { try { if (executionCanceledCallback) { onCancel(() => { if (this.state === processcube_engine_sdk_1.FlowNodeInstanceState.suspended || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.running || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.canceled) { executionCanceledCallback(); } }); } this.validateMessage(); this.onInterruptedCallback = () => { this.messageEventService.unsubscribe(this.onMessageSubscriptionId); this.abortSignal.abort(); }; await this.parseTriggerValue(); const receivedMessage = await this.suspendAndWaitForMessage(); const canceledByEventBasedGateway = await this.passTriggerThroughEventBasedGatwwayIfNecessary(); if (canceledByEventBasedGateway) { this.cancel(this.processToken); return; } this.processToken = receivedMessage?.currentToken ?? {}; const nextFlowNodeInfo = this.processInstance.getProcessModelFacade().getNextFlowNodesFor(this.messageCatchEvent); return resolve(nextFlowNodeInfo); } catch (error) { return reject(error); } }, { signal: this.abortSignal.signal }); } async resumeAfterSuspend(flowNodeInstance, resumptionCanceledCallback) { this.abortSignal.signal.throwIfAborted(); return new AbortablePromise_1.AbortablePromise(async (resolve, reject, onCancel) => { try { if (resumptionCanceledCallback) { onCancel(() => { if (this.state === processcube_engine_sdk_1.FlowNodeInstanceState.suspended || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.running || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.canceled) { resumptionCanceledCallback(); } }); } this.onInterruptedCallback = () => { this.messageEventService.unsubscribe(this.onMessageSubscriptionId); this.abortSignal.abort(); }; this.triggerValue = flowNodeInstance.triggerValue; const receivedMessagePromise = this.waitForMessage(); this.publishIntermediateCatchEventReachedNotification(); const receivedMessage = await receivedMessagePromise; const canceledByEventBasedGateway = await this.passTriggerThroughEventBasedGatwwayIfNecessary(); if (canceledByEventBasedGateway) { this.cancel(this.processToken); return; } this.processToken = receivedMessage?.currentToken ?? {}; const nextFlowNodeInfo = this.processInstance.getProcessModelFacade().getNextFlowNodesFor(this.messageCatchEvent); return resolve(nextFlowNodeInfo); } catch (error) { return reject(error); } }, { signal: this.abortSignal.signal }); } async suspendAndWaitForMessage() { this.abortSignal.signal.throwIfAborted(); const waitForMessagePromise = this.waitForMessage(); await this.persistOnSuspend(); return waitForMessagePromise; } async waitForMessage() { this.abortSignal.signal.throwIfAborted(); this.logger.debug(`Waiting for a "${this.messageCatchEvent.messageEventDefinition.name}" Message`); return new Promise((resolve) => { const messageReceivedCallback = async (message) => { if (this.abortSignal.signal.aborted) { this.messageEventService.acknowledge(message.eventId); return; } this.logger.debug(`MessageCatchEvent instance ${this.flowNodeInstanceId} received message:`, { receivedMessage: message, }); this.triggeredByFlowNodeInstanceId = message.flowNodeInstanceId; this.acknowledgeEventReceivedId = message.eventId; resolve(message); }; this.onMessageSubscriptionId = this.messageEventService.onMessage(this.messageCatchEvent.messageEventDefinition.name, messageReceivedCallback, true, this.processInstance.getProcessInstanceId(), this.triggerValue, this.messageCatchEvent.messageChannel); }); } validateMessage() { if (this.messageCatchEvent.messageEventDefinition?.name === undefined) { const errorToThrow = new processcube_engine_sdk_1.BadRequestError('Intermediate Message Catch Event does not have a message name assigned.', 'process'); errorToThrow.additionalInformation = { flowNodeInstanceId: this.flowNodeInstanceId, flowNodeId: this.messageCatchEvent.id, flowNodeName: this.messageCatchEvent.name, processInstanceId: this.processInstance.getProcessInstanceId(), processModelId: this.processInstance.getProcessModelId(), embeddedProcessModelId: this.processInstance.getEmbeddedProcessModelId(), correlationId: this.processInstance.getCorrelationId(), }; throw errorToThrow; } } async parseTriggerValue() { if (!this.messageCatchEvent.triggerValueInToken) { return; } this.abortSignal.signal.throwIfAborted(); try { this.triggerValue = await this.processInstance.executeRuntimeExpression({ expression: `\`${this.messageCatchEvent.triggerValueInToken}\``, currentFlowNode: this.messageCatchEvent, currentToken: this.processToken, previousFlowNode: this.processInstance.getProcessModelFacade().getPreviousFlowNodesFor(this.flowNode)?.pop(), allowNonObjectResults: true, }); } catch (error) { const errorToThrow = new processcube_engine_sdk_1.BadRequestError(`MessageCatchEvent configuration for setTriggerValueInToken is invalid!`, error.category); errorToThrow.additionalInformation = { setTriggerValueInToken: this.messageCatchEvent.triggerValueInToken, processInstanceId: this.processInstance.getProcessInstanceId(), correlationId: this.processInstance.getCorrelationId(), }; this.logger.error(errorToThrow.message); throw errorToThrow; } } }; exports.IntermediateMessageCatchEventHandler = IntermediateMessageCatchEventHandler; exports.IntermediateMessageCatchEventHandler = IntermediateMessageCatchEventHandler = __decorate([ (0, inversify_1.injectable)(), __metadata("design:paramtypes", [EventMiddlewareHandler_1.EventMiddlewareHandler, FlowNodeHandlerFactory_1.FlowNodeHandlerFactory, index_2.FlowNodeInstanceDatabaseAdapter, Object, ProcessInstance_1.ProcessInstance, MessageEventService_1.MessageEventService]) ], IntermediateMessageCatchEventHandler); //# sourceMappingURL=IntermediateMessageCatchEventHandler.js.map