public virtual IProcessInstance Execute(ICommandContext commandContext) { DeploymentManager deploymentCache = commandContext.ProcessEngineConfiguration.DeploymentManager; IProcessDefinition processDefinition = deploymentCache.FindDeployedProcessDefinitionById(processDefinitionId); if (processDefinition == null) { throw new ActivitiObjectNotFoundException("No process definition found for id '" + processDefinitionId + "'", typeof(IProcessDefinition)); } ProcessInstanceHelper processInstanceHelper = commandContext.ProcessEngineConfiguration.ProcessInstanceHelper; // Get model from cache Process process = ProcessDefinitionUtil.GetProcess(processDefinition.Id); if (process == null) { throw new ActivitiException("Cannot start process instance. Process model " + processDefinition.Name + " (id = " + processDefinition.Id + ") could not be found"); } FlowElement initialFlowElement = process.FlowElements.FirstOrDefault(x => x.Id == activityId); IProcessInstance processInstance = processInstanceHelper.CreateAndStartProcessInstanceWithInitialFlowElement(processDefinition, businessKey, processInstanceName, initialFlowElement, process, processVariables, transientVariables, startProcessInstance); return(processInstance); }
public override void Execute(IExecutionEntity execution) { IExecutionEntity executionEntity = execution; BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; Process process = ProcessDefinitionUtil.GetProcess(execution.ProcessDefinitionId); if (process == null) { throw new ActivitiException("Process model (id = " + execution.Id + ") could not be found"); } Activity compensationActivity = null; IList <Association> associations = process.FindAssociationsWithSourceRefRecursive(boundaryEvent.Id); foreach (Association association in associations) { FlowElement targetElement = process.GetFlowElement(association.TargetRef, true); if (targetElement is Activity activity) { if (activity.ForCompensation) { compensationActivity = activity; break; } } } if (compensationActivity == null) { throw new ActivitiException("Compensation activity could not be found (or it is missing 'isForCompensation=\"true\"'"); } // find SubProcess or Process instance execution IExecutionEntity scopeExecution = null; IExecutionEntity parentExecution = executionEntity.Parent; while (scopeExecution == null && parentExecution != null) { if (parentExecution.CurrentFlowElement is SubProcess) { scopeExecution = parentExecution; } else if (parentExecution.ProcessInstanceType) { scopeExecution = parentExecution; } else { parentExecution = parentExecution.Parent; } } if (scopeExecution == null) { throw new ActivitiException("Could not find a scope execution for compensation boundary event " + boundaryEvent.Id); } Context.CommandContext.EventSubscriptionEntityManager.InsertCompensationEvent(scopeExecution, compensationActivity.Id); }
public virtual IList <FlowElement> Execute(ICommandContext commandContext) { Cfg.ProcessEngineConfigurationImpl processEngineConfiguration = commandContext.ProcessEngineConfiguration; Interceptor.ICommandExecutor commandExecutor = processEngineConfiguration.CommandExecutor; IHistoricActivityInstanceQuery query = processEngineConfiguration.HistoryService.CreateHistoricActivityInstanceQuery() .SetProcessInstanceId(processInstanceId); if (finished.HasValue) { if (finished.Value) { query.SetFinished(); } else { query.SetUnfinished(); } } IList <IHistoricActivityInstance> list = query.OrderByHistoricActivityInstanceStartTime().Desc().List(); string processDefinitionId = list[0].ProcessDefinitionId; Process process = ProcessDefinitionUtil.GetProcess(processDefinitionId); IList <FlowElement> elements = new List <FlowElement>(); foreach (var actInst in list) { elements.Add(process.GetFlowElement(actInst.ActivityId, true)); } return(elements.Distinct().ToList()); }
public override void Execute(IExecutionEntity execution) { ThrowEvent throwEvent = (ThrowEvent)execution.CurrentFlowElement; /* * From the BPMN 2.0 spec: * * The Activity to be compensated MAY be supplied. * * If an Activity is not supplied, then the compensation is broadcast to all completed Activities in * the current Sub- Process (if present), or the entire Process instance (if at the global level). This "throws" the compensation. */ string activityRef = compensateEventDefinition.ActivityRef; ICommandContext commandContext = Context.CommandContext; IEventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.EventSubscriptionEntityManager; IList <ICompensateEventSubscriptionEntity> eventSubscriptions = new List <ICompensateEventSubscriptionEntity>(); if (!string.IsNullOrWhiteSpace(activityRef)) { // If an activity ref is provided, only that activity is compensated ((List <ICompensateEventSubscriptionEntity>)eventSubscriptions).AddRange(eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, activityRef)); } else { // If no activity ref is provided, it is broadcast to the current sub process / process instance Process process = ProcessDefinitionUtil.GetProcess(execution.ProcessDefinitionId); IFlowElementsContainer flowElementsContainer; if (throwEvent.SubProcess == null) { flowElementsContainer = process; } else { flowElementsContainer = throwEvent.SubProcess; } foreach (FlowElement flowElement in flowElementsContainer.FlowElements) { if (flowElement is Activity) { ((List <ICompensateEventSubscriptionEntity>)eventSubscriptions).AddRange(eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, flowElement.Id)); } } } if (eventSubscriptions.Count == 0) { Leave(execution); } else { // TODO: implement async (waitForCompletion=false in bpmn) ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false); Leave(execution); } }
/// <summary> /// /// </summary> /// <param name="timerEntity"></param> /// <param name="variableScope"></param> protected internal virtual void RestoreExtraData(IJobEntity timerEntity, IVariableScope variableScope) { string activityId = timerEntity.JobHandlerConfiguration; if (timerEntity.JobHandlerType.Equals(TimerStartEventJobHandler.TYPE, StringComparison.CurrentCultureIgnoreCase) || timerEntity.JobHandlerType.Equals(TriggerTimerEventJobHandler.TYPE, StringComparison.CurrentCultureIgnoreCase)) { activityId = TimerEventHandler.GetActivityIdFromConfiguration(timerEntity.JobHandlerConfiguration); string endDateExpressionString = TimerEventHandler.GetEndDateFromConfiguration(timerEntity.JobHandlerConfiguration); if (!(endDateExpressionString is null)) { IExpression endDateExpression = processEngineConfiguration.ExpressionManager.CreateExpression(endDateExpressionString); string endDateString = null; IBusinessCalendar businessCalendar = processEngineConfiguration.BusinessCalendarManager.GetBusinessCalendar(GetBusinessCalendarName(TimerEventHandler.GeCalendarNameFromConfiguration(timerEntity.JobHandlerConfiguration), variableScope)); if (endDateExpression != null) { object endDateValue = endDateExpression.GetValue(variableScope); if (endDateValue is string) { endDateString = (string)endDateValue; } else if (endDateValue is DateTime) { timerEntity.EndDate = (DateTime)endDateValue; } else { throw new ActivitiException("Timer '" + ((IExecutionEntity)variableScope).ActivityId + "' was not configured with a valid duration/time, either hand in a java.util.Date or a String in format 'yyyy-MM-dd'T'hh:mm:ss'"); } if (!timerEntity.EndDate.HasValue) { timerEntity.EndDate = businessCalendar.ResolveEndDate(endDateString).GetValueOrDefault(); } } } } int maxIterations = 1; if (!(timerEntity.ProcessDefinitionId is null)) { Process process = ProcessDefinitionUtil.GetProcess(timerEntity.ProcessDefinitionId); maxIterations = GetMaxIterations(process, activityId); if (maxIterations <= 1) { maxIterations = GetMaxIterations(process, activityId); } } timerEntity.MaxIterations = maxIterations; }
public virtual void ExecuteTaskListeners(ITaskEntity taskEntity, string eventType) { if (taskEntity.ProcessDefinitionId is object) { Process process = ProcessDefinitionUtil.GetProcess(taskEntity.ProcessDefinitionId); FlowElement flowElement = process.GetFlowElement(taskEntity.TaskDefinitionKey, true); if (flowElement is UserTask userTask) { ExecuteTaskListeners(userTask, taskEntity, eventType); } } }
public virtual void Execute(IJobEntity job, string configuration, IExecutionEntity execution, ICommandContext commandContext) { IProcessDefinitionEntity processDefinitionEntity = ProcessDefinitionUtil.GetProcessDefinitionFromDatabase(job.ProcessDefinitionId); // From DB -> need to get latest suspended state if (processDefinitionEntity == null) { throw new ActivitiException("Could not find process definition needed for timer start event"); } try { if (!processDefinitionEntity.Suspended) { if (commandContext.EventDispatcher.Enabled) { commandContext.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateEntityEvent(ActivitiEventType.TIMER_FIRED, job)); } // Find initial flow element matching the signal start event Process process = ProcessDefinitionUtil.GetProcess(job.ProcessDefinitionId); string activityId = GetActivityIdFromConfiguration(configuration); if (string.IsNullOrWhiteSpace(activityId) == false) { FlowElement flowElement = process.GetFlowElement(activityId, true); if (flowElement == null) { throw new ActivitiException("Could not find matching FlowElement for activityId " + activityId); } ProcessInstanceHelper processInstanceHelper = commandContext.ProcessEngineConfiguration.ProcessInstanceHelper; processInstanceHelper.CreateAndStartProcessInstanceWithInitialFlowElement(processDefinitionEntity, null, null, flowElement, process, null, null, true); } else { (new StartProcessInstanceCmd(processDefinitionEntity.Key, null, null, null, job.TenantId)).Execute(commandContext); } } else { log.LogDebug($"ignoring timer of suspended process definition {processDefinitionEntity.Name}"); } } catch (Exception e) { log.LogError($"exception during timer execution: {e.Message}"); throw new ActivitiException("exception during timer execution: " + e.Message, e); } }
/// <summary> /// /// </summary> protected override void RunOperation() { try { /* * Algorithm: for each execution that is involved in this command context, * * 1) Get its process definition * 2) Verify if its process definitions has any InactiveActivityBehavior behaviours. * 3) If so, verify if there are any executions inactive in those activities * 4) Execute the inactivated behavior * */ foreach (IExecutionEntity executionEntity in involvedExecutions) { Process process = ProcessDefinitionUtil.GetProcess(executionEntity.ProcessDefinitionId); ICollection <string> flowNodeIdsWithInactivatedBehavior = new List <string>(); foreach (FlowNode flowNode in process.FindFlowElementsOfType <FlowNode>()) { if (flowNode.Behavior is IInactiveActivityBehavior) { flowNodeIdsWithInactivatedBehavior.Add(flowNode.Id); } } if (flowNodeIdsWithInactivatedBehavior.Count > 0) { ICollection <IExecutionEntity> inactiveExecutions = commandContext.ExecutionEntityManager.FindInactiveExecutionsByProcessInstanceId(executionEntity.ProcessInstanceId); foreach (IExecutionEntity inactiveExecution in inactiveExecutions) { if (!inactiveExecution.IsActive && flowNodeIdsWithInactivatedBehavior.Contains(inactiveExecution.ActivityId) && !inactiveExecution.Deleted) { FlowNode flowNode = (FlowNode)process.GetFlowElement(inactiveExecution.ActivityId, true); IInactiveActivityBehavior inactiveActivityBehavior = ((IInactiveActivityBehavior)flowNode.Behavior); log.LogDebug($"Found InactiveActivityBehavior instance of class {inactiveActivityBehavior.GetType()} that can be executed on activity '{flowNode.Id}'"); inactiveActivityBehavior.ExecuteInactive(inactiveExecution); } } } } } catch (Exception ex) { log.LogError(ex, ex.Message); throw; } }
/// <summary> /// To be used in an <seealso cref="ActivityBehavior"/> or <seealso cref="ICSharpDelegate"/>: leaves /// the current activity via one specific sequenceflow. /// </summary> public static void LeaveDelegate(IExecutionEntity delegateExecution, string sequenceFlowId) { string processDefinitionId = delegateExecution.ProcessDefinitionId; Process process = ProcessDefinitionUtil.GetProcess(processDefinitionId); FlowElement flowElement = process.FindFlowElement(sequenceFlowId); if (flowElement is SequenceFlow) { delegateExecution.CurrentFlowElement = flowElement; Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(delegateExecution, false); } else { throw new ActivitiException(sequenceFlowId + " does not match a sequence flow"); } }
/// <summary> /// Helper method to match the activityId of an execution with a FlowElement of the process definition referenced by the execution. /// </summary> protected internal virtual FlowElement GetCurrentFlowElement(IExecutionEntity execution) { if (execution.CurrentFlowElement != null) { return(execution.CurrentFlowElement); } else if (execution.CurrentActivityId is object) { string processDefinitionId = execution.ProcessDefinitionId; Process process = ProcessDefinitionUtil.GetProcess(processDefinitionId); string activityId = execution.CurrentActivityId; FlowElement currentFlowElement = process.GetFlowElement(activityId, true); return(currentFlowElement); } return(null); }
public virtual void HandleEvent(IEventSubscriptionEntity eventSubscription, object payload, ICommandContext commandContext) { string configuration = eventSubscription.Configuration; if (configuration is null) { throw new ActivitiException("Compensating execution not set for compensate event subscription with id " + eventSubscription.Id); } IExecutionEntity compensatingExecution = commandContext.ExecutionEntityManager.FindById <IExecutionEntity>(configuration); string processDefinitionId = compensatingExecution.ProcessDefinitionId; Process process = ProcessDefinitionUtil.GetProcess(processDefinitionId); if (process == null) { throw new ActivitiException("Cannot start process instance. Process model (id = " + processDefinitionId + ") could not be found"); } FlowElement flowElement = process.GetFlowElement(eventSubscription.ActivityId, true); if (flowElement is SubProcess && !((SubProcess)flowElement).ForCompensation) { // descend into scope: compensatingExecution.IsScope = true; IList <ICompensateEventSubscriptionEntity> eventsForThisScope = commandContext.EventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(compensatingExecution.Id); ScopeUtil.ThrowCompensationEvent(eventsForThisScope, compensatingExecution, false); } else { try { if (commandContext.ProcessEngineConfiguration.EventDispatcher.Enabled) { commandContext.ProcessEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_COMPENSATE, flowElement.Id, flowElement.Name, compensatingExecution.Id, compensatingExecution.ProcessInstanceId, compensatingExecution.ProcessDefinitionId, flowElement)); } compensatingExecution.CurrentFlowElement = flowElement; Context.Agenda.PlanContinueProcessInCompensation(compensatingExecution); } catch (Exception e) { throw new ActivitiException("Error while handling compensation event " + eventSubscription, e); } } }
public override void HandleEvent(IEventSubscriptionEntity eventSubscription, object payload, ICommandContext commandContext) { if (eventSubscription.ExecutionId is object) { base.HandleEvent(eventSubscription, payload, commandContext); } else if (eventSubscription.ProcessDefinitionId is object) { // Find initial flow element matching the signal start event string processDefinitionId = eventSubscription.ProcessDefinitionId; IProcessDefinition processDefinition = ProcessDefinitionUtil.GetProcessDefinition(processDefinitionId); if (processDefinition == null) { throw new ActivitiObjectNotFoundException("No process definition found for id '" + processDefinitionId + "'", typeof(IProcessDefinition)); } if (processDefinition.Suspended) { throw new ActivitiException("Could not handle signal: process definition with id: " + processDefinitionId + " is suspended"); } Process process = ProcessDefinitionUtil.GetProcess(processDefinitionId); FlowElement flowElement = process.GetFlowElement(eventSubscription.ActivityId, true); if (flowElement == null) { throw new ActivitiException("Could not find matching FlowElement for activityId " + eventSubscription.ActivityId); } // Start process instance via that flow element IDictionary <string, object> variables = null; if (payload is System.Collections.IDictionary) { variables = (IDictionary <string, object>)payload; } ProcessInstanceHelper processInstanceHelper = commandContext.ProcessEngineConfiguration.ProcessInstanceHelper; processInstanceHelper.CreateAndStartProcessInstanceWithInitialFlowElement(processDefinition, null, null, flowElement, process, variables, null, true); } else { throw new ActivitiException("Invalid signal handling: no execution nor process definition set"); } }
protected internal virtual void restorePreviousStartEventsIfNeeded(IProcessDefinition processDefinition) { IProcessDefinitionEntity latestProcessDefinition = findLatestProcessDefinition(processDefinition); if (processDefinition.Id.Equals(latestProcessDefinition.Id)) { // Try to find a previous version (it could be some versions are missing due to deletions) IProcessDefinition previousProcessDefinition = findNewLatestProcessDefinitionAfterRemovalOf(processDefinition); if (previousProcessDefinition != null) { BpmnModel bpmnModel = ProcessDefinitionUtil.GetBpmnModel(previousProcessDefinition.Id); Process previousProcess = ProcessDefinitionUtil.GetProcess(previousProcessDefinition.Id); if (CollectionUtil.IsNotEmpty(previousProcess.FlowElements)) { IList <StartEvent> startEvents = previousProcess.FindFlowElementsOfType <StartEvent>(); if (CollectionUtil.IsNotEmpty(startEvents)) { foreach (StartEvent startEvent in startEvents) { if (CollectionUtil.IsNotEmpty(startEvent.EventDefinitions)) { EventDefinition eventDefinition = startEvent.EventDefinitions[0]; if (eventDefinition is TimerEventDefinition) { restoreTimerStartEvent(previousProcessDefinition, startEvent, eventDefinition); } else if (eventDefinition is SignalEventDefinition) { restoreSignalStartEvent(previousProcessDefinition, bpmnModel, startEvent, eventDefinition); } else if (eventDefinition is MessageEventDefinition) { restoreMessageStartEvent(previousProcessDefinition, bpmnModel, startEvent, eventDefinition); } } } } } } } }
protected internal virtual void ValidateAndSwitchVersionOfExecution(ICommandContext commandContext, IExecutionEntity execution, IProcessDefinition newProcessDefinition) { // check that the new process definition version contains the current activity Process process = ProcessDefinitionUtil.GetProcess(newProcessDefinition.Id); if (!(execution.ActivityId is null) && process.GetFlowElement(execution.ActivityId, true) == null) { throw new ActivitiException("The new process definition " + "(key = '" + newProcessDefinition.Key + "') " + "does not contain the current activity " + "(id = '" + execution.ActivityId + "') " + "of the process instance " + "(id = '" + processInstanceId + "')."); } // switch the process instance to the new process definition version execution.ProcessDefinitionId = newProcessDefinition.Id; execution.ProcessDefinitionName = newProcessDefinition.Name; execution.ProcessDefinitionKey = newProcessDefinition.Key; // and change possible existing tasks (as the process definition id is stored there too) IList <ITaskEntity> tasks = commandContext.TaskEntityManager.FindTasksByExecutionId(execution.Id); foreach (ITaskEntity taskEntity in tasks) { taskEntity.ProcessDefinitionId = newProcessDefinition.Id; commandContext.HistoryManager.RecordTaskProcessDefinitionChange(taskEntity.Id, newProcessDefinition.Id); } }
public override void Execute(IExecutionEntity execution) { string finalProcessDefinitonKey; if (processDefinitionExpression != null) { finalProcessDefinitonKey = (string)processDefinitionExpression.GetValue(execution); } else { finalProcessDefinitonKey = processDefinitonKey; } IProcessDefinition processDefinition = FindProcessDefinition(finalProcessDefinitonKey, execution.TenantId); // Get model from cache Process subProcess = ProcessDefinitionUtil.GetProcess(processDefinition.Id); if (subProcess == null) { throw new ActivitiException("Cannot start a sub process instance. Process model " + processDefinition.Name + " (id = " + processDefinition.Id + ") could not be found"); } FlowElement initialFlowElement = subProcess.InitialFlowElement; if (initialFlowElement == null) { throw new ActivitiException("No start element found for process definition " + processDefinition.Id); } // Do not start a process instance if the process definition is suspended if (ProcessDefinitionUtil.IsProcessDefinitionSuspended(processDefinition.Id)) { throw new ActivitiException("Cannot start process instance. Process definition " + processDefinition.Name + " (id = " + processDefinition.Id + ") is suspended"); } ProcessEngineConfigurationImpl processEngineConfiguration = Context.ProcessEngineConfiguration; IExecutionEntityManager executionEntityManager = Context.CommandContext.ExecutionEntityManager; ExpressionManager expressionManager = processEngineConfiguration.ExpressionManager; CallActivity callActivity = (CallActivity)execution.CurrentFlowElement; string businessKey = null; if (!string.IsNullOrWhiteSpace(callActivity.BusinessKey)) { IExpression expression = expressionManager.CreateExpression(callActivity.BusinessKey); businessKey = expression.GetValue(execution).ToString(); } else if (callActivity.InheritBusinessKey) { IExecutionEntity processInstance = executionEntityManager.FindById <IExecutionEntity>(execution.ProcessInstanceId); businessKey = processInstance.BusinessKey; } IExecutionEntity subProcessInstance = Context.CommandContext.ExecutionEntityManager.CreateSubprocessInstance(processDefinition, execution, businessKey); Context.CommandContext.HistoryManager.RecordSubProcessInstanceStart(execution, subProcessInstance, initialFlowElement); // process template-defined data objects IDictionary <string, object> variables = ProcessDataObjects(subProcess.DataObjects); if (callActivity.InheritVariables) { IDictionary <string, object> executionVariables = execution.Variables; foreach (KeyValuePair <string, object> entry in executionVariables.SetOfKeyValuePairs()) { variables[entry.Key] = entry.Value; } } // copy process variables foreach (IOParameter ioParameter in callActivity.InParameters) { object value = null; if (!string.IsNullOrWhiteSpace(ioParameter.SourceExpression)) { IExpression expression = expressionManager.CreateExpression(ioParameter.SourceExpression.Trim()); value = expression.GetValue(execution); } else { value = execution.GetVariable(ioParameter.Source); } variables[ioParameter.Target] = value; } if (variables.Count > 0) { InitializeVariables(subProcessInstance, variables); } // Create the first execution that will visit all the process definition elements IExecutionEntity subProcessInitialExecution = executionEntityManager.CreateChildExecution(subProcessInstance); subProcessInitialExecution.CurrentFlowElement = initialFlowElement; Context.Agenda.PlanContinueProcessOperation(subProcessInitialExecution); Context.ProcessEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateProcessStartedEvent(subProcessInitialExecution, variables, false)); }
/// <summary> /// /// </summary> /// <param name="processInstanceExecution"></param> protected internal virtual void HandleProcessInstanceExecution(IExecutionEntity processInstanceExecution) { IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager; string processInstanceId = processInstanceExecution.Id; // No parent execution == process instance id logger.LogDebug($"No parent execution found. Verifying if process instance {processInstanceId} can be stopped."); IExecutionEntity superExecution = processInstanceExecution.SuperExecution; ISubProcessActivityBehavior subProcessActivityBehavior = null; // copy variables before destroying the ended sub process instance (call activity) if (superExecution != null) { FlowNode superExecutionElement = (FlowNode)superExecution.CurrentFlowElement; subProcessActivityBehavior = (ISubProcessActivityBehavior)superExecutionElement.Behavior; try { subProcessActivityBehavior.Completing(superExecution, processInstanceExecution); } //catch (Exception e) //{ // //logger.error("Error while completing sub process of execution {}", processInstanceExecution, e); // throw e; //} catch (Exception e) { logger.LogError($"Error while completing sub process of execution {processInstanceExecution}.Exception Message: {e.Message}"); throw new ActivitiException("Error while completing sub process of execution " + processInstanceExecution, e); } } int activeExecutions = GetNumberOfActiveChildExecutionsForProcessInstance(executionEntityManager, processInstanceId, superExecution); if (activeExecutions == 0) { logger.LogDebug($"No active executions found. Ending process instance {processInstanceId} "); // note the use of execution here vs processinstance execution for getting the flowelement executionEntityManager.DeleteProcessInstanceExecutionEntity(processInstanceId, execution.CurrentFlowElement?.Id, null, false, false); } else { logger.LogDebug($"Active executions found. Process instance {processInstanceId} will not be ended."); } Process process = ProcessDefinitionUtil.GetProcess(processInstanceExecution.ProcessDefinitionId); // Execute execution listeners for process end. if (CollectionUtil.IsNotEmpty(process.ExecutionListeners)) { ExecuteExecutionListeners(process, processInstanceExecution, BaseExecutionListenerFields.EVENTNAME_END); } // and trigger execution afterwards if doing a call activity if (superExecution != null) { superExecution.SubProcessInstance = null; try { subProcessActivityBehavior.Completed(superExecution); } //catch (Exception e) //{ // logger.error("Error while completing sub process of execution {}", processInstanceExecution, e); // throw e; //} catch (Exception e) { logger.LogError($"Error while completing sub process of execution {processInstanceExecution}. Exception Messgae: {e.Message}."); throw new ActivitiException("Error while completing sub process of execution " + processInstanceExecution, e); } } }
/// <summary> /// /// </summary> protected internal virtual void ExecuteProcessStartExecutionListeners() { Process process = ProcessDefinitionUtil.GetProcess(execution.ProcessDefinitionId); ExecuteExecutionListeners(process, execution.Parent, BaseExecutionListenerFields.EVENTNAME_START); }
protected internal override Process GetProcessDefinition(string processDefinitionId) { return(ProcessDefinitionUtil.GetProcess(processDefinitionId)); }
protected internal virtual Process GetProcessDefinition(string processDefinitionId) { // TODO: must be extracted / cache should be accessed in another way return(ProcessDefinitionUtil.GetProcess(processDefinitionId)); }
protected internal static IDictionary <string, IList <Event> > FindCatchingEventsForProcess(string processDefinitionId, string errorCode) { IDictionary <string, IList <Event> > eventMap = new Dictionary <string, IList <Event> >(); Process process = ProcessDefinitionUtil.GetProcess(processDefinitionId); BpmnModel bpmnModel = ProcessDefinitionUtil.GetBpmnModel(processDefinitionId); string compareErrorCode = RetrieveErrorCode(bpmnModel, errorCode); IList <EventSubProcess> subProcesses = process.FindFlowElementsOfType <EventSubProcess>(true); foreach (EventSubProcess eventSubProcess in subProcesses) { foreach (FlowElement flowElement in eventSubProcess.FlowElements) { if (flowElement is StartEvent startEvent) { if (CollectionUtil.IsNotEmpty(startEvent.EventDefinitions) && startEvent.EventDefinitions[0] is ErrorEventDefinition) { ErrorEventDefinition errorEventDef = (ErrorEventDefinition)startEvent.EventDefinitions[0]; string eventErrorCode = RetrieveErrorCode(bpmnModel, errorEventDef.ErrorCode); if (eventErrorCode is null || compareErrorCode is null || eventErrorCode.Equals(compareErrorCode)) { IList <Event> startEvents = new List <Event> { startEvent }; eventMap[eventSubProcess.Id] = startEvents; } } } } } IList <BoundaryEvent> boundaryEvents = process.FindFlowElementsOfType <BoundaryEvent>(true); foreach (BoundaryEvent boundaryEvent in boundaryEvents) { if (boundaryEvent.AttachedToRefId is object && CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is ErrorEventDefinition) { ErrorEventDefinition errorEventDef = (ErrorEventDefinition)boundaryEvent.EventDefinitions[0]; string eventErrorCode = RetrieveErrorCode(bpmnModel, errorEventDef.ErrorCode); if (eventErrorCode is null || compareErrorCode is null || eventErrorCode.Equals(compareErrorCode)) { IList <Event> elementBoundaryEvents = null; if (!eventMap.ContainsKey(boundaryEvent.AttachedToRefId)) { elementBoundaryEvents = new List <Event>(); eventMap[boundaryEvent.AttachedToRefId] = elementBoundaryEvents; } else { elementBoundaryEvents = eventMap[boundaryEvent.AttachedToRefId]; } elementBoundaryEvents.Add(boundaryEvent); } } } return(eventMap); }
protected internal static void ExecuteCatch(IDictionary <string, IList <Event> > eventMap, IExecutionEntity delegateExecution, string errorId) { Event matchingEvent = null; IExecutionEntity currentExecution = delegateExecution; IExecutionEntity parentExecution; if ((eventMap?.ContainsKey(currentExecution.ActivityId)).GetValueOrDefault(false)) { matchingEvent = eventMap[currentExecution.ActivityId][0]; // Check for multi instance if (currentExecution.ParentId is object && currentExecution.Parent.IsMultiInstanceRoot) { parentExecution = currentExecution.Parent; } else { parentExecution = currentExecution; } } else { parentExecution = currentExecution.Parent; // Traverse parents until one is found that is a scope and matches the activity the boundary event is defined on while (matchingEvent == null && parentExecution != null) { IFlowElementsContainer currentContainer = null; if (parentExecution.CurrentFlowElement is IFlowElementsContainer) { currentContainer = (IFlowElementsContainer)parentExecution.CurrentFlowElement; } else if (parentExecution.Id.Equals(parentExecution.ProcessInstanceId)) { currentContainer = ProcessDefinitionUtil.GetProcess(parentExecution.ProcessDefinitionId); } foreach (string refId in eventMap.Keys) { IList <Event> events = eventMap[refId]; if (CollectionUtil.IsNotEmpty(events) && events[0] is StartEvent) { if (currentContainer.FindFlowElement(refId) != null) { matchingEvent = events[0]; } } } if (matchingEvent == null) { if ((eventMap?.ContainsKey(parentExecution.ActivityId)).GetValueOrDefault(false)) { matchingEvent = eventMap[parentExecution.ActivityId][0]; // Check for multi instance if (parentExecution.ParentId is object && parentExecution.Parent.IsMultiInstanceRoot) { parentExecution = parentExecution.Parent; } } else if (!string.IsNullOrWhiteSpace(parentExecution.ParentId)) { parentExecution = parentExecution.Parent; } else { parentExecution = null; } } } } if (matchingEvent != null && parentExecution != null) { ExecuteEventHandler(matchingEvent, parentExecution, currentExecution, errorId); } else { throw new ActivitiException("No matching parent execution for error code " + errorId + " found"); } }