Ejemplo n.º 1
0
        protected internal virtual void ExecuteInterruptingBehavior(IExecutionEntity executionEntity, ICommandContext commandContext)
        {
            // The destroy scope operation will look for the parent execution and
            // destroy the whole scope, and leave the boundary event using this parent execution.
            //
            // The take outgoing seq flows operation below (the non-interrupting else clause) on the other hand uses the
            // child execution to leave, which keeps the scope alive.
            // Which is what we need here.

            IExecutionEntityManager executionEntityManager    = commandContext.ExecutionEntityManager;
            IExecutionEntity        attachedRefScopeExecution = executionEntityManager.FindById <IExecutionEntity>(executionEntity.ParentId);

            IExecutionEntity parentScopeExecution       = null;
            IExecutionEntity currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(attachedRefScopeExecution.ParentId);

            while (currentlyExaminedExecution != null && parentScopeExecution == null)
            {
                if (currentlyExaminedExecution.IsScope)
                {
                    parentScopeExecution = currentlyExaminedExecution;
                }
                else
                {
                    currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                }
            }

            DeleteChildExecutions(attachedRefScopeExecution, executionEntity, commandContext);

            // set new parent for boundary event execution
            executionEntity.Parent = parentScopeExecution ?? throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event");

            Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(executionEntity, true);
        }
Ejemplo n.º 2
0
        protected internal virtual void ExecuteNonInterruptingBehavior(IExecutionEntity executionEntity, ICommandContext commandContext)
        {
            // Non-interrupting: the current execution is given the first parent
            // scope (which isn't its direct parent)
            //
            // Why? Because this execution does NOT have anything to do with
            // the current parent execution (the one where the boundary event is on): when it is deleted or whatever,
            // this does not impact this new execution at all, it is completely independent in that regard.

            // Note: if the parent of the parent does not exists, this becomes a concurrent execution in the process instance!

            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            IExecutionEntity parentExecutionEntity = executionEntityManager.FindById <IExecutionEntity>(executionEntity.ParentId);

            IExecutionEntity scopeExecution             = null;
            IExecutionEntity currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(parentExecutionEntity.ParentId);

            GetScopeExecution(executionEntityManager, ref scopeExecution, ref currentlyExaminedExecution);

            if (scopeExecution == null)
            {
                throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event");
            }

            IExecutionEntity nonInterruptingExecution = executionEntityManager.CreateChildExecution(scopeExecution);

            nonInterruptingExecution.CurrentFlowElement = executionEntity.CurrentFlowElement;

            Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(nonInterruptingExecution, true);
        }
Ejemplo n.º 3
0
        public virtual IExecutionEntity Execute(ICommandContext commandContext)
        {
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;
            IExecutionEntity        scopeExecution         = null;
            IExecutionEntity        currentExecution       = currentlyExaminedExecution;

            while (currentExecution != null && scopeExecution == null)
            {
                if (currentExecution.IsScope)
                {
                    scopeExecution = currentExecution;
                    break;
                }
                else
                {
                    currentExecution = currentExecution.Parent;
                }
            }
            if (scopeExecution == null)
            {
                while (currentlyExaminedExecution != null && scopeExecution == null)
                {
                    if (currentlyExaminedExecution.IsScope)
                    {
                        scopeExecution = currentlyExaminedExecution;
                    }
                    else
                    {
                        currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                    }
                }
            }

            return(scopeExecution);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// we create a separate execution for each compensation handler invocation.
        /// </summary>
        public static void ThrowCompensationEvent(IList <ICompensateEventSubscriptionEntity> eventSubscriptions, IExecutionEntity execution, bool async)
        {
            IExecutionEntityManager executionEntityManager = Context.CommandContext.ExecutionEntityManager;

            // first spawn the compensating executions
            foreach (IEventSubscriptionEntity eventSubscription in eventSubscriptions)
            {
                IExecutionEntity compensatingExecution = null;

                // check whether compensating execution is already created (which is the case when compensating an embedded subprocess,
                // where the compensating execution is created when leaving the subprocess and holds snapshot data).
                if (eventSubscription.Configuration is object)
                {
                    compensatingExecution              = executionEntityManager.FindById <IExecutionEntity>(eventSubscription.Configuration);
                    compensatingExecution.Parent       = compensatingExecution.ProcessInstance;
                    compensatingExecution.IsEventScope = false;
                }
                else
                {
                    compensatingExecution           = executionEntityManager.CreateChildExecution(execution);
                    eventSubscription.Configuration = compensatingExecution.Id;
                }
            }

            // signal compensation events in reverse order of their 'created' timestamp
            eventSubscriptions.OrderBy(x => x, new ComparatorAnonymousInnerClass());

            foreach (ICompensateEventSubscriptionEntity compensateEventSubscriptionEntity in eventSubscriptions)
            {
                Context.CommandContext.EventSubscriptionEntityManager.EventReceived(compensateEventSubscriptionEntity, null, async);
            }
        }
        public virtual object Execute(ICommandContext commandContext)
        {
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;
            IExecutionEntity        execution = executionEntityManager.FindById <IExecutionEntity>(executionId);

            if (execution == null)
            {
                throw new ActivitiObjectNotFoundException("No execution found for id '" + executionId + "'", typeof(IExecutionEntity));
            }

            if (!(execution.CurrentFlowElement is AdhocSubProcess))
            {
                throw new ActivitiException("The current flow element of the requested execution is not an ad-hoc sub process");
            }

            IList <IExecutionEntity> childExecutions = execution.Executions;

            if (childExecutions.Count > 0)
            {
                throw new ActivitiException("Ad-hoc sub process has running child executions that need to be completed first");
            }

            IExecutionEntity outgoingFlowExecution = executionEntityManager.CreateChildExecution(execution.Parent);

            outgoingFlowExecution.CurrentFlowElement = execution.CurrentFlowElement;

            executionEntityManager.DeleteExecutionAndRelatedData(execution, null, false);

            Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(outgoingFlowExecution, true);

            return(null);
        }
        protected internal virtual void DefaultTerminateEndEventBehaviour(IExecutionEntity execution, ICommandContext commandContext, IExecutionEntityManager executionEntityManager)
        {
            IExecutionEntity scopeExecutionEntity = executionEntityManager.FindFirstScope(execution);

            SendProcessInstanceCancelledEvent(scopeExecutionEntity, execution.CurrentFlowElement);

            // If the scope is the process instance, we can just terminate it all
            // Special treatment is needed when the terminated activity is a subprocess (embedded/callactivity/..)
            // The subprocess is destroyed, but the execution calling it, continues further on.
            // In case of a multi-instance subprocess, only one instance is terminated, the other instances continue to exist.

            string deleteReason = CreateDeleteReason(execution.CurrentActivityId);

            if (scopeExecutionEntity.ProcessInstanceType && scopeExecutionEntity.SuperExecutionId is null)
            {
                EndAllHistoricActivities(scopeExecutionEntity.Id, deleteReason);
                DeleteExecutionEntities(executionEntityManager, scopeExecutionEntity, deleteReason);
                commandContext.HistoryManager.RecordProcessInstanceEnd(scopeExecutionEntity.Id, deleteReason, execution.CurrentActivityId);
            }
            else if (scopeExecutionEntity.CurrentFlowElement != null && scopeExecutionEntity.CurrentFlowElement is SubProcess)
            { // SubProcess
                SubProcess subProcess = (SubProcess)scopeExecutionEntity.CurrentFlowElement;

                scopeExecutionEntity.DeleteReason = deleteReason;
                if (subProcess.HasMultiInstanceLoopCharacteristics())
                {
                    Context.Agenda.PlanDestroyScopeOperation(scopeExecutionEntity);
                    MultiInstanceActivityBehavior multiInstanceBehavior = (MultiInstanceActivityBehavior)subProcess.Behavior;
                    multiInstanceBehavior.Leave(scopeExecutionEntity);
                }
                else
                {
                    Context.Agenda.PlanDestroyScopeOperation(scopeExecutionEntity);
                    IExecutionEntity outgoingFlowExecution = executionEntityManager.CreateChildExecution(scopeExecutionEntity.Parent);
                    outgoingFlowExecution.CurrentFlowElement = scopeExecutionEntity.CurrentFlowElement;
                    Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(outgoingFlowExecution, true);
                }
            }
            else if (scopeExecutionEntity.ParentId is null && scopeExecutionEntity.SuperExecutionId is object)
            { // CallActivity
                IExecutionEntity callActivityExecution = scopeExecutionEntity.SuperExecution;
                CallActivity     callActivity          = (CallActivity)callActivityExecution.CurrentFlowElement;

                if (callActivity.HasMultiInstanceLoopCharacteristics())
                {
                    MultiInstanceActivityBehavior multiInstanceBehavior = (MultiInstanceActivityBehavior)callActivity.Behavior;
                    multiInstanceBehavior.Leave(callActivityExecution);
                    executionEntityManager.DeleteProcessInstanceExecutionEntity(scopeExecutionEntity.Id, execution.CurrentFlowElement.Id, "terminate end event", false, false);
                }
                else
                {
                    executionEntityManager.DeleteProcessInstanceExecutionEntity(scopeExecutionEntity.Id, execution.CurrentFlowElement.Id, "terminate end event", false, false);
                    IExecutionEntity superExecutionEntity = executionEntityManager.FindById <IExecutionEntity>(scopeExecutionEntity.SuperExecutionId);
                    Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(superExecutionEntity, true);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Returns the first parent execution of the provided execution that is a scope.
        /// </summary>
        protected internal virtual IExecutionEntity FindFirstParentScopeExecution(IExecutionEntity executionEntity)
        {
            IExecutionEntityManager executionEntityManager     = commandContext.ExecutionEntityManager;
            IExecutionEntity        parentScopeExecution       = null;
            IExecutionEntity        currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(executionEntity.ParentId);

            while (currentlyExaminedExecution != null && parentScopeExecution == null)
            {
                if (currentlyExaminedExecution.IsScope)
                {
                    parentScopeExecution = currentlyExaminedExecution;
                }
                else
                {
                    currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                }
            }
            return(parentScopeExecution);
        }
Ejemplo n.º 8
0
 private static void GetScopeExecution(IExecutionEntityManager executionEntityManager, ref IExecutionEntity scopeExecution, ref IExecutionEntity currentlyExaminedExecution)
 {
     while (currentlyExaminedExecution != null && scopeExecution == null)
     {
         if (currentlyExaminedExecution.IsScope)
         {
             scopeExecution = currentlyExaminedExecution;
         }
         else
         {
             currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
         }
     }
 }
Ejemplo n.º 9
0
        public virtual object Execute(ICommandContext commandContext)
        {
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;
            IExecutionEntity        processInstance        = executionEntityManager.FindById <IExecutionEntity>(processInstanceId);

            if (processInstance == null)
            {
                throw new ActivitiObjectNotFoundException("Cannot find process instance with id " + processInstanceId, typeof(IExecutionEntity));
            }

            IIdentityLinkEntityManager identityLinkEntityManager = commandContext.IdentityLinkEntityManager;

            identityLinkEntityManager.AddIdentityLink(processInstance, userId, groupId, type);
            commandContext.HistoryManager.CreateProcessInstanceIdentityLinkComment(processInstanceId, userId, groupId, type, true);

            return(null);
        }
Ejemplo n.º 10
0
        public virtual IList <string> Execute(ICommandContext commandContext)
        {
            if (executionId is null)
            {
                throw new ActivitiIllegalArgumentException("executionId is null");
            }

            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;
            IExecutionEntity        execution = executionEntityManager.FindById <IExecutionEntity>(executionId);

            if (execution == null)
            {
                throw new ActivitiObjectNotFoundException("execution " + executionId + " doesn't exist", typeof(IExecution));
            }

            return(FindActiveActivityIds(execution));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// we create a separate execution for each compensation handler invocation.
        /// </summary>
        public static void ThrowCompensationEvent(IList <ICompensateEventSubscriptionEntity> eventSubscriptions, IExecutionEntity execution, bool async)
        {
            IExecutionEntityManager executionEntityManager = Context.CommandContext.ExecutionEntityManager;

            // first spawn the compensating executions
            foreach (IEventSubscriptionEntity eventSubscription in eventSubscriptions)
            {
                IExecutionEntity compensatingExecution = null;

                // check whether compensating execution is already created (which is the case when compensating an embedded subprocess,
                // where the compensating execution is created when leaving the subprocess and holds snapshot data).
                if (!(eventSubscription.Configuration is null))
                {
                    compensatingExecution              = executionEntityManager.FindById <IExecutionEntity>(eventSubscription.Configuration);
                    compensatingExecution.Parent       = compensatingExecution.ProcessInstance;
                    compensatingExecution.IsEventScope = false;
                }
        public virtual object Execute(ICommandContext commandContext)
        {
            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.");
            }

            executionManager.UpdateProcessInstanceBusinessKey(processInstance, businessKey);

            return(null);
        }
Ejemplo n.º 13
0
        protected internal virtual void LockFirstParentScope(IExecutionEntity execution)
        {
            IExecutionEntityManager executionEntityManager = Context.CommandContext.ExecutionEntityManager;

            bool             found = false;
            IExecutionEntity parentScopeExecution = null;

            while (!found && execution is object && execution.ParentId is object)
            {
                parentScopeExecution = executionEntityManager.FindById <IExecutionEntity>(execution.ParentId);
                if (parentScopeExecution != null && parentScopeExecution.IsScope)
                {
                    found = true;
                }
                execution = parentScopeExecution;
            }

            parentScopeExecution.ForceUpdate();
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
0
        public static void PropagateError(string errorCode, IExecutionEntity execution)
        {
            IDictionary <string, IList <Event> > eventMap = FindCatchingEventsForProcess(execution.ProcessDefinitionId, errorCode);

            if (eventMap.Count > 0)
            {
                ExecuteCatch(eventMap, execution, errorCode);
            }
            else if (!execution.ProcessInstanceId.Equals(execution.RootProcessInstanceId))
            { // Call activity
                IExecutionEntityManager executionEntityManager   = Context.CommandContext.ExecutionEntityManager;
                IExecutionEntity        processInstanceExecution = executionEntityManager.FindById <IExecutionEntity>(execution.ProcessInstanceId);
                if (processInstanceExecution != null)
                {
                    IExecutionEntity parentExecution = processInstanceExecution.SuperExecution;

                    IList <string> toDeleteProcessInstanceIds = new List <string>
                    {
                        execution.ProcessInstanceId
                    };

                    while (parentExecution != null && eventMap.Count == 0)
                    {
                        eventMap = FindCatchingEventsForProcess(parentExecution.ProcessDefinitionId, errorCode);
                        if (eventMap.Count > 0)
                        {
                            foreach (string processInstanceId in toDeleteProcessInstanceIds)
                            {
                                IExecutionEntity processInstanceEntity = executionEntityManager.FindById <IExecutionEntity>(processInstanceId);

                                // Delete
                                executionEntityManager.DeleteProcessInstanceExecutionEntity(processInstanceEntity.Id, execution.CurrentFlowElement?.Id, "ERROR_EVENT " + errorCode, false, false);

                                // Event
                                ProcessEngineConfigurationImpl processEngineConfiguration = Context.ProcessEngineConfiguration;
                                if (!(processEngineConfiguration is null) && Context.ProcessEngineConfiguration.EventDispatcher.Enabled)
                                {
                                    processEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateEntityEvent(ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT, processInstanceEntity));
                                }
                            }
                            ExecuteCatch(eventMap, parentExecution, errorCode);
                        }
                        else
                        {
                            toDeleteProcessInstanceIds.Add(parentExecution.ProcessInstanceId);
                            IExecutionEntity superExecution = parentExecution.SuperExecution;
                            if (superExecution != null)
                            {
                                parentExecution = superExecution;
                            }
                            else if (!parentExecution.Id.Equals(parentExecution.RootProcessInstanceId))
                            { // stop at the root
                                parentExecution = parentExecution.ProcessInstance;
                            }
                            else
                            {
                                parentExecution = null;
                            }
                        }
                    }
                }
            }

            if (eventMap.Count == 0)
            {
                throw new BpmnError(errorCode, "No catching boundary event found for error with errorCode '" + errorCode + "', neither in same process nor in parent process");
            }
        }
Ejemplo n.º 16
0
        public override void Execute(IExecutionEntity execution)
        {
            IExecutionEntity        executionEntity        = execution;
            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            // find cancel boundary event:
            IExecutionEntity parentScopeExecution       = null;
            IExecutionEntity currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(executionEntity.ParentId);

            while (currentlyExaminedExecution != null && parentScopeExecution == null)
            {
                if (currentlyExaminedExecution.CurrentFlowElement is SubProcess)
                {
                    parentScopeExecution = currentlyExaminedExecution;
                    SubProcess subProcess = (SubProcess)currentlyExaminedExecution.CurrentFlowElement;
                    if (subProcess.LoopCharacteristics != null)
                    {
                        IExecutionEntity miExecution = parentScopeExecution.Parent;
                        FlowElement      miElement   = miExecution.CurrentFlowElement;
                        if (miElement != null && miElement.Id.Equals(subProcess.Id))
                        {
                            parentScopeExecution = miExecution;
                        }
                    }
                }
                else
                {
                    currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                }
            }

            if (parentScopeExecution == null)
            {
                throw new ActivitiException("No sub process execution found for cancel end event " + executionEntity.CurrentActivityId);
            }

            {
                SubProcess    subProcess          = (SubProcess)parentScopeExecution.CurrentFlowElement;
                BoundaryEvent cancelBoundaryEvent = null;
                if (CollectionUtil.IsNotEmpty(subProcess.BoundaryEvents))
                {
                    foreach (BoundaryEvent boundaryEvent in subProcess.BoundaryEvents)
                    {
                        if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CancelEventDefinition)
                        {
                            cancelBoundaryEvent = boundaryEvent;
                            break;
                        }
                    }
                }

                if (cancelBoundaryEvent == null)
                {
                    throw new ActivitiException("Could not find cancel boundary event for cancel end event " + executionEntity.CurrentActivityId);
                }

                IExecutionEntity newParentScopeExecution = null;
                currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(parentScopeExecution.ParentId);
                while (currentlyExaminedExecution != null && newParentScopeExecution == null)
                {
                    if (currentlyExaminedExecution.IsScope)
                    {
                        newParentScopeExecution = currentlyExaminedExecution;
                    }
                    else
                    {
                        currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                    }
                }

                ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentScopeExecution);

                if (subProcess.LoopCharacteristics != null)
                {
                    IList <IExecutionEntity> multiInstanceExecutions = parentScopeExecution.Executions;
                    IList <IExecutionEntity> executionsToDelete      = new List <IExecutionEntity>();
                    foreach (IExecutionEntity multiInstanceExecution in multiInstanceExecutions)
                    {
                        if (!multiInstanceExecution.Id.Equals(parentScopeExecution.Id))
                        {
                            ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(multiInstanceExecution);

                            // end all executions in the scope of the transaction
                            executionsToDelete.Add(multiInstanceExecution);
                            DeleteChildExecutions(multiInstanceExecution, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                        }
                    }

                    foreach (IExecutionEntity executionEntityToDelete in executionsToDelete)
                    {
                        DeleteChildExecutions(executionEntityToDelete, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                    }
                }

                // The current activity is finished (and will not be ended in the deleteChildExecutions)
                commandContext.HistoryManager.RecordActivityEnd(executionEntity, null);

                // set new parent for boundary event execution
                executionEntity.Parent             = newParentScopeExecution ?? throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event " + cancelBoundaryEvent.Id);
                executionEntity.CurrentFlowElement = cancelBoundaryEvent;

                // end all executions in the scope of the transaction
                DeleteChildExecutions(parentScopeExecution, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                commandContext.HistoryManager.RecordActivityEnd(parentScopeExecution, History.DeleteReasonFields.TRANSACTION_CANCELED);

                Context.Agenda.PlanTriggerExecutionOperation(executionEntity);
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        ///
        /// </summary>
        protected internal virtual void HandleRegularExecution()
        {
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            // There will be a parent execution (or else we would be in the process instance handling method)
            IExecutionEntity parentExecution = executionEntityManager.FindById <IExecutionEntity>(execution.ParentId);

            // If the execution is a scope, all the child executions must be deleted first.
            if (execution.IsScope)
            {
                executionEntityManager.DeleteChildExecutions(execution, null, false);
            }

            // Delete current execution
            logger.LogDebug($"Ending execution {execution.Id}");
            executionEntityManager.DeleteExecutionAndRelatedData(execution, null, false);

            logger.LogDebug($"Parent execution found. Continuing process using execution {parentExecution.Id}");

            // When ending an execution in a multi instance subprocess , special care is needed
            if (IsEndEventInMultiInstanceSubprocess(execution))
            {
                HandleMultiInstanceSubProcess(executionEntityManager, parentExecution);
                return;
            }

            SubProcess subProcess = execution.CurrentFlowElement.SubProcess;

            // If there are no more active child executions, the process can be continued
            // If not (eg an embedded subprocess still has active elements, we cannot continue)
            if (GetNumberOfActiveChildExecutionsForExecution(executionEntityManager, parentExecution.Id) == 0 || IsAllEventScopeExecutions(executionEntityManager, parentExecution))
            {
                IExecutionEntity executionToContinue = null;

                if (subProcess != null)
                {
                    // In case of ending a subprocess: go up in the scopes and continue via the parent scope
                    // unless its a compensation, then we don't need to do anything and can just end it

                    if (subProcess.ForCompensation)
                    {
                        Context.Agenda.PlanEndExecutionOperation(parentExecution);
                    }
                    else
                    {
                        executionToContinue = HandleSubProcessEnd(executionEntityManager, parentExecution, subProcess);
                    }
                }
                else
                {
                    // In the 'regular' case (not being in a subprocess), we use the parent execution to
                    // continue process instance execution

                    executionToContinue = HandleRegularExecutionEnd(executionEntityManager, parentExecution);
                }

                if (executionToContinue != null)
                {
                    // only continue with outgoing sequence flows if the execution is
                    // not the process instance root execution (otherwise the process instance is finished)
                    if (executionToContinue.ProcessInstanceType)
                    {
                        HandleProcessInstanceExecution(executionToContinue);
                    }
                    else
                    {
                        Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(executionToContinue, true);
                    }
                }
            }
        }
Ejemplo n.º 18
0
        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));
        }