Exemple #1
0
        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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #5
0
        /// <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;
        }
Exemple #6
0
 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);
         }
     }
 }
Exemple #7
0
        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;
            }
        }
Exemple #9
0
        /// <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);
                }
            }
        }
Exemple #12
0
        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");
            }
        }
Exemple #13
0
        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #14
0
        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);
                }
            }
        }
Exemple #17
0
        /// <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));
 }
Exemple #19
0
 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");
            }
        }