UNPKG

@5minds/processcube_engine

Version:

The ProcessCube Engine. Stores and executes BPMNs.

239 lines • 13.8 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); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IntermediateConditionalCatchEventHandler = void 0; const async_lock_1 = __importDefault(require("async-lock")); 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 EventAggregator_1 = require("../../../Tools/EventAggregator"); const EventMiddlewareHandler_1 = require("../../../Tools/EventMiddlewareHandler"); const ProcessInstance_1 = require("../../ProcessInstance"); const FlowNodeHandlerFactory_1 = require("../FlowNodeHandlerFactory"); const EventHandler_1 = require("./EventHandler"); const asyncLocker = new async_lock_1.default({ maxPending: 1000000 }); let IntermediateConditionalCatchEventHandler = class IntermediateConditionalCatchEventHandler extends EventHandler_1.EventHandler { eventSubscriptions = []; hasConditionBeenFulfilled; constructor(eventMiddlewareHandler, flowNodeHandlerFactory, flowNodeInstanceDatabaseAdapter, conditionalCatchEventModel, processInstance) { super(eventMiddlewareHandler, flowNodeHandlerFactory, flowNodeInstanceDatabaseAdapter, conditionalCatchEventModel, processInstance, 'conditional_catch_event_handler'); } get conditionalCatchEvent() { return this.flowNode; } async persistOnSuspend() { this.abortSignal.signal.throwIfAborted(); await super.persistOnSuspend(undefined, { type: index_1.FlowNodeInstanceDataTypes.catchEvent, eventName: this.conditionalCatchEvent.name, }); this.publishIntermediateCatchEventReachedNotification(); } async persistOnExit() { await super.persistOnExit({ type: index_1.FlowNodeInstanceDataTypes.catchEvent, eventName: this.conditionalCatchEvent.name, triggeredByFlowNodeInstanceId: this.triggeredByFlowNodeInstanceId, }); this.publishIntermediateCatchEventFinishedNotification(); } async persistOnError(error) { await super.persistOnError(error); this.publishIntermediateCatchEventFinishedNotification(); } async persistOnTerminate() { await super.persistOnTerminate(); this.publishIntermediateCatchEventFinishedNotification(); } async startExecution(executionCanceledCallback) { this.abortSignal.signal.throwIfAborted(); this.logger.debug(`Executing ConditionalCatchEvent instance.`); return this.executeHandler(executionCanceledCallback); } async executeHandler(executionCanceledCallback) { this.abortSignal.signal.throwIfAborted(); return new AbortablePromise_1.AbortablePromise(async (resolve, reject, onCancel) => { 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(); } }); } try { this.onInterruptedCallback = () => { if (this.abortSignal.signal.aborted) { return; } this.cancelEventSubscriptions(); this.abortSignal.abort(); }; const waitForConditionFulfillmentPromise = this.waitForConditionFulfillment(); await this.persistOnSuspend(); await waitForConditionFulfillmentPromise; const canceledByEventBasedGateway = await this.passTriggerThroughEventBasedGatwwayIfNecessary(); if (canceledByEventBasedGateway) { this.cancel(this.processToken); return; } const nextFlowNodeInfo = this.processInstance.getProcessModelFacade().getNextFlowNodesFor(this.conditionalCatchEvent); 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) => { 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(); } }); } try { this.onInterruptedCallback = () => { if (this.abortSignal.signal.aborted) { return; } this.cancelEventSubscriptions(); this.abortSignal.abort(); }; const waitForFullfilmentPromise = this.waitForConditionFulfillment(); this.publishIntermediateCatchEventReachedNotification(); await waitForFullfilmentPromise; const canceledByEventBasedGateway = await this.passTriggerThroughEventBasedGatwwayIfNecessary(); if (canceledByEventBasedGateway) { this.cancel(this.processToken); return; } const nextFlowNodeInfo = this.processInstance.getProcessModelFacade().getNextFlowNodesFor(this.conditionalCatchEvent); return resolve(nextFlowNodeInfo); } catch (error) { return reject(error); } }, { signal: this.abortSignal.signal }); } async waitForConditionFulfillment() { this.abortSignal.signal.throwIfAborted(); this.logger.debug(`IntermediateConditionalCatchEvent instance ${this.flowNodeInstanceId} waiting for condition to be fulfilled"`); const isConditionFulfilled = await this.executeAndCheckCondition(); if (isConditionFulfilled) { return; } return new Promise((resolve) => { const onTokenMayHaveChanged = async (event, eventName) => { EventAggregator_1.EventAggregator.acknowledgeEvent(event.eventId); this.abortSignal.signal.throwIfAborted(); const isConditionFulfilled = await asyncLocker.acquire(`IntermediateConditionalEventHandler-${this.flowNodeInstanceId}-CheckCondition`, async () => { if (this.hasConditionBeenFulfilled) { return false; } if (event.processInstanceId !== this.processInstance.getProcessInstanceId() && !(eventName === index_1.eventAggregatorSettings.messagePaths.correlationMetadataChanged && event.correlationId === this.processInstance.getCorrelationId())) { return false; } return await this.executeAndCheckCondition(); }); if (isConditionFulfilled) { this.cancelEventSubscriptions(); this.triggeredByFlowNodeInstanceId = event.flowNodeInstanceId; this.hasConditionBeenFulfilled = true; return resolve(); } }; this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.activityFinished, onTokenMayHaveChanged)); this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.intermediateCatchEventFinished, onTokenMayHaveChanged)); this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.intermediateThrowEventTriggered, onTokenMayHaveChanged)); this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.tokenPayloadChangeFinished, onTokenMayHaveChanged)); this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.correlationMetadataChanged, onTokenMayHaveChanged)); this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.processInstanceMetadataChanged, onTokenMayHaveChanged)); this.eventSubscriptions.push(EventAggregator_1.EventAggregator.subscribe(index_1.eventAggregatorSettings.messagePaths.processInstanceOwnerChanged.replace(index_1.eventAggregatorSettings.messageParams.processInstanceId, this.processInstance.getProcessInstanceId()), onTokenMayHaveChanged)); }); } async cancelEventSubscriptions() { this.eventSubscriptions.forEach(EventAggregator_1.EventAggregator.unsubscribe); this.eventSubscriptions = []; } async executeAndCheckCondition() { this.abortSignal.signal.throwIfAborted(); const conditionExpression = this.conditionalCatchEvent.conditionalEventDefinition?.condition; try { if (!conditionExpression) { const conditionMissingError = new processcube_engine_sdk_1.BadRequestError('Condition is missing.'); conditionMissingError.additionalInformation = { ...this.getAdditionalInformationForError(), }; throw conditionMissingError; } const result = await this.processInstance.executeRuntimeExpression({ expression: this.conditionalCatchEvent.conditionalEventDefinition.condition, currentFlowNode: this.conditionalCatchEvent, currentToken: this.processToken, previousFlowNode: this.processInstance.getProcessModelFacade().getPreviousFlowNodesFor(this.flowNode)?.pop(), allowNonObjectResults: true, }); if (result === true) { this.logger.debug(`IntermediateConditionalCatchEvent instance ${this.flowNodeInstanceId} fulfilled`); this.cancelEventSubscriptions(); return true; } if (result != false) { const invalidExpressionError = new processcube_engine_sdk_1.BadRequestError('Condition did not evaluate to a boolean expression'); invalidExpressionError.additionalInformation = { ...this.getAdditionalInformationForError(), }; throw invalidExpressionError; } return false; } catch (err) { err.additionalInformation = { flowNodeInstanceId: this.flowNodeInstanceId, flowNodeType: this.flowNode.bpmnType, flowNodeId: this.flowNode.id, processModelId: this.processInstance.getProcessModelId(), embeddedProcessModelId: this.processInstance.getEmbeddedProcessModelId(), processInstanceId: this.processInstance.getProcessInstanceId(), correlationId: this.processInstance.getCorrelationId(), }; this.logger.error(err); throw err; } } getAdditionalInformationForError() { return { flowNodeId: this.flowNode.id, flowNodeInstanceId: this.flowNodeInstanceId, processModelId: this.processInstance.getProcessModelId(), embeddedProcessModelId: this.processInstance.getEmbeddedProcessModelId(), processInstanceId: this.processInstance.getProcessInstanceId(), correlationId: this.processInstance.getCorrelationId(), }; } }; exports.IntermediateConditionalCatchEventHandler = IntermediateConditionalCatchEventHandler; exports.IntermediateConditionalCatchEventHandler = IntermediateConditionalCatchEventHandler = __decorate([ (0, inversify_1.injectable)(), __metadata("design:paramtypes", [EventMiddlewareHandler_1.EventMiddlewareHandler, FlowNodeHandlerFactory_1.FlowNodeHandlerFactory, index_2.FlowNodeInstanceDatabaseAdapter, Object, ProcessInstance_1.ProcessInstance]) ], IntermediateConditionalCatchEventHandler); //# sourceMappingURL=IntermediateConditionalCatchEventHandler.js.map