import { ICorrelationService, IExecutionContextFacade, IFlowNodeInstanceRepository, Runtime, } from '@process-engine/process_engine_contracts'; import {IIAMService} from '@essential-projects/iam_contracts'; export class CorrelationService implements ICorrelationService { private _flowNodeInstanceRepository: IFlowNodeInstanceRepository; private _iamService: IIAMService; constructor(flowNodeInstanceRepository: IFlowNodeInstanceRepository, iamService: IIAMService) { this._flowNodeInstanceRepository = flowNodeInstanceRepository; this._iamService = iamService; } private get flowNodeInstanceRepository(): IFlowNodeInstanceRepository { return this._flowNodeInstanceRepository; } private get iamService(): IIAMService { return this._iamService; } public async getAllActiveCorrelations(executionContextFacade: IExecutionContextFacade): Promise> { const activeFlowNodeInstances: Array = await this._getActiveFlowNodeInstances(); const activeCorrelations: Array = await this._getActiveCorrelationsFromFlowNodeList(activeFlowNodeInstances); return activeCorrelations; } /** * Queries all "running" and "suspended" FlowNodeInstances from the repository * and returns them as a concatenated result. */ private async _getActiveFlowNodeInstances(): Promise> { const runningFlowNodeInstances: Array = await this._getRunningFlowNodeInstances(); const suspendedFlowNodeInstances: Array = await this._getSuspendedFlowNodeInstances(); Array.prototype.push.apply(runningFlowNodeInstances, suspendedFlowNodeInstances); return runningFlowNodeInstances; } /** * Queries all running and suspended FlowNodeInstances from the repository * and returns them as a concatenated result. * * @returns A list of all retrieved FlowNodeInstances. */ private async _getRunningFlowNodeInstances(): Promise> { const runningState: Runtime.Types.FlowNodeInstanceState = Runtime.Types.FlowNodeInstanceState.running; const runningFlowNodeInstances: Array = await this.flowNodeInstanceRepository.queryByState(runningState); return runningFlowNodeInstances; } /** * Returns all running FlowNodeInstances from the repository. * * @returns A list of all retrieved FlowNodeInstances. */ private async _getSuspendedFlowNodeInstances(): Promise> { const suspendedState: Runtime.Types.FlowNodeInstanceState = Runtime.Types.FlowNodeInstanceState.suspended; const suspendedFlowNodeInstances: Array = await this.flowNodeInstanceRepository.queryByState(suspendedState); return suspendedFlowNodeInstances; } private _getActiveCorrelationsFromFlowNodeList(flowNodes: Array): Array { const correlations: Array = []; const correlationsContainsMatchingEntry: Function = (flowNode: Runtime.Types.FlowNodeInstance): boolean => { return correlations.some((correlation: Runtime.Types.Correlation) => { const hasMatchingToken: boolean = flowNode.tokens.some((token: Runtime.Types.ProcessToken): boolean => { return token.correlationId === correlation.id; }); return hasMatchingToken; }); }; for (const flowNode of flowNodes) { if (!correlationsContainsMatchingEntry(flowNode)) { const correlation: Runtime.Types.Correlation = this._createCorrelationFromFlowNodeInstance(flowNode); correlations.push(correlation); } } return correlations; } private _createCorrelationFromFlowNodeInstance(flowNode: Runtime.Types.FlowNodeInstance): Runtime.Types.Correlation { // Note that correlationid and processModelId will be the same for all of the tokens associated with the FNI. // Therefore it doesn't matter which one is being used here. const correlation: Runtime.Types.Correlation = new Runtime.Types.Correlation(); correlation.id = flowNode.tokens[0].correlationId; correlation.processModelId = flowNode.tokens[0].processModelId; correlation.state = flowNode.state; return correlation; } }