示例#1
0
        public override void Trigger(IExecutionEntity execution, string triggerName, object triggerData, bool throwError = true)
        {
            BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement;

            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            IExecutionEntity subProcessExecution = null;
            // TODO: this can be optimized. A full search in the all executions shouldn't be needed
            IList <IExecutionEntity> processInstanceExecutions = executionEntityManager.FindChildExecutionsByProcessInstanceId(execution.ProcessInstanceId);

            foreach (IExecutionEntity childExecution in processInstanceExecutions)
            {
                if (childExecution.CurrentFlowElement != null && childExecution.CurrentFlowElement.Id.Equals(boundaryEvent.AttachedToRefId))
                {
                    subProcessExecution = childExecution;
                    break;
                }
            }

            if (subProcessExecution == null)
            {
                throw new ActivitiException("No execution found for sub process of boundary cancel event " + boundaryEvent.Id);
            }

            IEventSubscriptionEntityManager            eventSubscriptionEntityManager = commandContext.EventSubscriptionEntityManager;
            IList <ICompensateEventSubscriptionEntity> eventSubscriptions             = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(subProcessExecution.ParentId);

            if (eventSubscriptions.Count == 0)
            {
                Leave(execution);
            }
            else
            {
                Leave(execution);

                string deleteReason = History.DeleteReasonFields.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.Id + ")";

                // cancel boundary is always sync
                ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false);
                executionEntityManager.DeleteExecutionAndRelatedData(subProcessExecution, deleteReason, false);
                if (subProcessExecution.CurrentFlowElement is Activity activity)
                {
                    if (activity.LoopCharacteristics != null)
                    {
                        IExecutionEntity         miExecution       = subProcessExecution.Parent;
                        IList <IExecutionEntity> miChildExecutions = executionEntityManager.FindChildExecutionsByParentExecutionId(miExecution.Id);
                        foreach (IExecutionEntity miChildExecution in miChildExecutions)
                        {
                            if (subProcessExecution.Id.Equals(miChildExecution.Id) == false && activity.Id.Equals(miChildExecution.CurrentActivityId))
                            {
                                executionEntityManager.DeleteExecutionAndRelatedData(miChildExecution, deleteReason, false);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="executionEntityManager"></param>
        /// <param name="processInstanceId"></param>
        /// <returns></returns>
        protected internal virtual int GetNumberOfActiveChildExecutionsForProcessInstance(IExecutionEntityManager executionEntityManager, string processInstanceId)
        {
            ICollection <IExecutionEntity> executions = executionEntityManager.FindChildExecutionsByProcessInstanceId(processInstanceId);
            int activeExecutions = 0;

            foreach (IExecutionEntity execution in executions)
            {
                if (execution.IsActive && !processInstanceId.Equals(execution.Id))
                {
                    activeExecutions++;
                }
            }
            return(activeExecutions);
        }
        protected internal virtual void ExecuteInclusiveGatewayLogic(IExecutionEntity execution)
        {
            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            LockFirstParentScope(execution);

            ICollection <IExecutionEntity> allExecutions     = executionEntityManager.FindChildExecutionsByProcessInstanceId(execution.ProcessInstanceId);
            IEnumerator <IExecutionEntity> executionIterator = allExecutions.GetEnumerator();
            bool oneExecutionCanReachGateway = false;

            while (!oneExecutionCanReachGateway && executionIterator.MoveNext())
            {
                IExecutionEntity executionEntity = executionIterator.Current;
                if (!executionEntity.ActivityId.Equals(execution.CurrentActivityId))
                {
                    bool canReachGateway = ExecutionGraphUtil.IsReachable(execution.ProcessDefinitionId, executionEntity.ActivityId, execution.CurrentActivityId);
                    if (canReachGateway)
                    {
                        oneExecutionCanReachGateway = true;
                    }
                }
                else if (executionEntity.ActivityId.Equals(execution.CurrentActivityId) && executionEntity.IsActive)
                {
                    // Special case: the execution has reached the inc gw, but the operation hasn't been executed yet for that execution
                    oneExecutionCanReachGateway = true;
                }
            }

            // If no execution can reach the gateway, the gateway activates and executes fork behavior
            if (!oneExecutionCanReachGateway)
            {
                logger.LogDebug("Inclusive gateway cannot be reached by any execution and is activated");

                // Kill all executions here (except the incoming)
                ICollection <IExecutionEntity> executionsInGateway = executionEntityManager.FindInactiveExecutionsByActivityIdAndProcessInstanceId(execution.CurrentActivityId, execution.ProcessInstanceId);
                foreach (IExecutionEntity executionEntityInGateway in executionsInGateway)
                {
                    if (!executionEntityInGateway.Id.Equals(execution.Id))
                    {
                        commandContext.HistoryManager.RecordActivityEnd(executionEntityInGateway, null);
                        executionEntityManager.DeleteExecutionAndRelatedData(executionEntityInGateway, null, false);
                    }
                }

                // Leave
                commandContext.Agenda.PlanTakeOutgoingSequenceFlowsOperation(execution, true);
            }
        }
示例#4
0
        public virtual object Execute(ICommandContext commandContext)
        {
            // check that the new process definition is just another version of the same
            // process definition that the process instance is using
            IExecutionEntityManager executionManager = commandContext.ExecutionEntityManager;
            IExecutionEntity        processInstance  = executionManager.FindById <IExecutionEntity>(new KeyValuePair <string, object>("id", processInstanceId));

            if (processInstance == null)
            {
                throw new ActivitiObjectNotFoundException("No process instance found for id = '" + processInstanceId + "'.", typeof(IProcessInstance));
            }
            else if (!processInstance.ProcessInstanceType)
            {
                throw new ActivitiIllegalArgumentException("A process instance id is required, but the provided id " + "'" + processInstanceId + "' " + "points to a child execution of process instance " + "'" + processInstance.ProcessInstanceId + "'. " + "Please invoke the " + this.GetType().Name + " with a root execution id.");
            }

            DeploymentManager  deploymentCache          = commandContext.ProcessEngineConfiguration.DeploymentManager;
            IProcessDefinition currentProcessDefinition = deploymentCache.FindDeployedProcessDefinitionById(processInstance.ProcessDefinitionId);

            IProcessDefinition newProcessDefinition = deploymentCache.FindDeployedProcessDefinitionByKeyAndVersionAndTenantId(currentProcessDefinition.Key, processDefinitionVersion, currentProcessDefinition.TenantId);

            ValidateAndSwitchVersionOfExecution(commandContext, processInstance, newProcessDefinition);

            // switch the historic process instance to the new process definition version
            commandContext.HistoryManager.RecordProcessDefinitionChange(processInstanceId, newProcessDefinition.Id);

            // switch all sub-executions of the process instance to the new process definition version
            ICollection <IExecutionEntity> childExecutions = executionManager.FindChildExecutionsByProcessInstanceId(processInstanceId);

            foreach (IExecutionEntity executionEntity in childExecutions)
            {
                ValidateAndSwitchVersionOfExecution(commandContext, executionEntity, newProcessDefinition);
            }

            return(null);
        }