public virtual void HandleEvent(EventSubscriptionEntity eventSubscription, object payload,
                                        CommandContext commandContext)
        {
            VariableEvent variableEvent;

            if ((payload == null) || payload is VariableEvent)
            {
                variableEvent = (VariableEvent)payload;
            }
            else
            {
                throw new ProcessEngineException("Payload have to be " + typeof(VariableEvent).FullName +
                                                 ", to evaluate condition.");
            }

            ActivityImpl      activity         = eventSubscription.Activity;
            IActivityBehavior activityBehavior = activity.ActivityBehavior;

            if (activityBehavior is IConditionalEventBehavior)
            {
                var conditionalBehavior = (IConditionalEventBehavior)activityBehavior;
                conditionalBehavior.LeaveOnSatisfiedCondition(eventSubscription, variableEvent);
            }
            else
            {
                throw new ProcessEngineException("Conditional Event has not correct behavior: " + activityBehavior);
            }
        }
示例#2
0
        /// <summary>
        ///     <para>
        ///         Required for migrating active sequential MI receive tasks. These activities were formerly not scope,
        ///         but are now. This has the following implications:
        ///     </para>
        ///     <para>
        ///         Before migration:
        ///         <ul>
        ///             <li> the event subscription is attached to the miBody scope execution
        ///         </ul>
        ///     </para>
        ///     <para>
        ///         After migration:
        ///         <ul>
        ///             <li>
        ///                 a new subscription is created for every instance
        ///                 <li>
        ///                     the new subscription is attached to a dedicated scope execution as a child of the miBody scope
        ///                     execution
        ///         </ul>
        ///     </para>
        ///     <para>
        ///         Thus, this method removes the subscription on the miBody scope
        ///     </para>
        /// </summary>
        public static void RemoveLegacySubscriptionOnParent(ExecutionEntity execution,
                                                            EventSubscriptionEntity eventSubscription)
        {
            ActivityImpl activity = (ActivityImpl)execution.Activity;

            if (activity == null)
            {
                return;
            }

            IActivityBehavior behavior       = activity.ActivityBehavior;
            IActivityBehavior parentBehavior = (activity.FlowScope != null ? activity.FlowScope.ActivityBehavior : null);

            if (behavior is ReceiveTaskActivityBehavior && parentBehavior is MultiInstanceActivityBehavior)
            {
                IList <EventSubscriptionEntity> parentSubscriptions = ((ExecutionEntity)execution.Parent).EventSubscriptions;

                foreach (EventSubscriptionEntity subscription in parentSubscriptions)
                {
                    // distinguish a boundary event on the mi body with the same message name from the receive task subscription
                    if (AreEqualEventSubscriptions(subscription, eventSubscription))
                    {
                        subscription.Delete();
                    }
                }
            }
        }
        protected internal virtual void ExecuteCompensationBoundaryEvents(FlowElement flowElement, IExecutionEntity execution)
        {
            //Execute compensation boundary events
            ICollection <BoundaryEvent> boundaryEvents = FindBoundaryEventsForFlowNode(execution.ProcessDefinitionId, flowElement);

            if (CollectionUtil.IsNotEmpty(boundaryEvents))
            {
                // The parent execution becomes a scope, and a child execution is created for each of the boundary events
                foreach (BoundaryEvent boundaryEvent in boundaryEvents)
                {
                    if (CollectionUtil.IsEmpty(boundaryEvent.EventDefinitions))
                    {
                        continue;
                    }

                    if (boundaryEvent.EventDefinitions[0] is CompensateEventDefinition)
                    {
                        IExecutionEntity childExecutionEntity = Context.CommandContext.ExecutionEntityManager.CreateChildExecution(execution);
                        childExecutionEntity.ParentId           = execution.Id;
                        childExecutionEntity.CurrentFlowElement = boundaryEvent;
                        childExecutionEntity.IsScope            = false;

                        IActivityBehavior boundaryEventBehavior = ((IActivityBehavior)boundaryEvent.Behavior);
                        boundaryEventBehavior.Execute(childExecutionEntity);
                    }
                }
            }
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="flowNode"></param>
        protected internal virtual void ExecuteMultiInstanceSynchronous(FlowNode flowNode)
        {
            // Execution listener: event 'start'
            if (CollectionUtil.IsNotEmpty(flowNode.ExecutionListeners))
            {
                ExecuteExecutionListeners(flowNode, BaseExecutionListenerFields.EVENTNAME_START);
            }

            // Execute any boundary events, sub process boundary events will be executed from the activity behavior
            if (!inCompensation && flowNode is Activity)
            { // Only activities can have boundary events
                IList <BoundaryEvent> boundaryEvents = ((Activity)flowNode).BoundaryEvents;
                if (CollectionUtil.IsNotEmpty(boundaryEvents))
                {
                    ExecuteBoundaryEvents(boundaryEvents, execution);
                }
            }

            // Execute the multi instance behavior
            IActivityBehavior activityBehavior = (IActivityBehavior)flowNode.Behavior;

            if (activityBehavior != null)
            {
                ExecuteActivityBehavior(activityBehavior, flowNode);
            }
            else
            {
                throw new ActivitiException("Expected an activity behavior in flow node " + flowNode.Id);
            }
        }
示例#5
0
 // Adds properties to the given delegation instance (eg multi instance) if
 // needed
 protected internal virtual IActivityBehavior DetermineBehaviour(IActivityBehavior delegateInstance)
 {
     if (HasMultiInstanceCharacteristics())
     {
         multiInstanceActivityBehavior.InnerActivityBehavior = (AbstractBpmnActivityBehavior)delegateInstance;
         return(multiInstanceActivityBehavior);
     }
     return(delegateInstance);
 }
示例#6
0
        /// <summary>
        ///     Cannot create more than inner instance in a sequential MI construct
        /// </summary>
        protected internal virtual bool SupportsConcurrentChildInstantiation(ScopeImpl flowScope)
        {
            if (flowScope == null)
            {
                return(true);
            }
            IActivityBehavior behavior = flowScope.ActivityBehavior;

            return(behavior == null || !(behavior is SequentialMultiInstanceActivityBehavior));
        }
示例#7
0
        public virtual void Completed(IExecutionEntity execution)
        {
            if (activityBehaviorInstance == null)
            {
                activityBehaviorInstance = ActivityBehaviorInstance;
            }

            if (activityBehaviorInstance is ISubProcessActivityBehavior)
            {
                ((ISubProcessActivityBehavior)activityBehaviorInstance).Completed(execution);
            }
            else
            {
                throw new ActivitiException("completed() can only be called on a " + activityBehaviorInstance.GetType().FullName + " instance");
            }
        }
示例#8
0
        // Subprocess activityBehaviour
        public virtual void Completing(IExecutionEntity execution, IExecutionEntity subProcessInstance)
        {
            if (activityBehaviorInstance == null)
            {
                activityBehaviorInstance = ActivityBehaviorInstance;
            }

            if (activityBehaviorInstance is ISubProcessActivityBehavior)
            {
                ((ISubProcessActivityBehavior)activityBehaviorInstance).Completing(execution, subProcessInstance);
            }
            else
            {
                throw new ActivitiException("completing() can only be called on a " + typeof(SubProcessActivityBehavior).FullName + " instance");
            }
        }
示例#9
0
        // Signallable activity behavior
        public override void Trigger(IExecutionEntity execution, string signalName, object signalData, bool throwError = true)
        {
            if (activityBehaviorInstance == null)
            {
                activityBehaviorInstance = ActivityBehaviorInstance;
            }

            if (activityBehaviorInstance is ITriggerableActivityBehavior)
            {
                ((ITriggerableActivityBehavior)activityBehaviorInstance).Trigger(execution, signalName, signalData);
            }
            else
            {
                throw new ActivitiException("signal() can only be called on a " + typeof(ITriggerableActivityBehavior).FullName + " instance");
            }
        }
示例#10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="flowNode"></param>
        protected internal virtual void ExecuteSynchronous(FlowNode flowNode)
        {
            // Execution listener
            if (CollectionUtil.IsNotEmpty(flowNode.ExecutionListeners))
            {
                ExecuteExecutionListeners(flowNode, BaseExecutionListenerFields.EVENTNAME_START);
            }

            commandContext.HistoryManager.RecordActivityStart(execution);

            // Execute actual behavior
            IActivityBehavior activityBehavior = (IActivityBehavior)flowNode.Behavior;

            if (activityBehavior != null)
            {
                logger.LogDebug($"Executing activityBehavior {activityBehavior.GetType()} on activity '{flowNode.Id}' with execution {execution.Id}");

                ProcessEngineConfigurationImpl processEngineConfiguration = Context.ProcessEngineConfiguration;
                if (processEngineConfiguration != null && processEngineConfiguration.EventDispatcher.Enabled)
                {
                    processEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_STARTED, flowNode.Id, flowNode.Name, execution.Id, execution.ProcessInstanceId, execution.ProcessDefinitionId, flowNode));
                }

                try
                {
                    activityBehavior.Execute(execution);
                }
                catch (BpmnError error)
                {
                    // re-throw business fault so that it can be caught by an Error Intermediate Event or Error Event Sub-Process in the process
                    ErrorPropagation.PropagateError(error, execution);
                }
                catch (Exception e)
                {
                    if (LogMDC.MDCEnabled)
                    {
                        LogMDC.PutMDCExecution(execution);
                    }
                    throw e;
                }
            }
            else
            {
                logger.LogDebug($"No activityBehavior on activity '{flowNode.Id}' with execution {execution.Id}");
            }
        }
示例#11
0
        // Activity Behavior
        public override void Execute(IExecutionEntity execution)
        {
            bool isSkipExpressionEnabled = SkipExpressionUtil.IsSkipExpressionEnabled(execution, skipExpression);

            if (!isSkipExpressionEnabled || (isSkipExpressionEnabled && !SkipExpressionUtil.ShouldSkipFlowElement(execution, skipExpression)))
            {
                if (Context.ProcessEngineConfiguration.EnableProcessDefinitionInfoCache)
                {
                    JToken taskElementProperties = Context.GetBpmnOverrideElementProperties(serviceTaskId, execution.ProcessDefinitionId);
                    if (taskElementProperties != null && taskElementProperties[DynamicBpmnConstants.SERVICE_TASK_CLASS_NAME] != null)
                    {
                        string overrideClassName = taskElementProperties[DynamicBpmnConstants.SERVICE_TASK_CLASS_NAME].ToString();
                        if (!string.IsNullOrWhiteSpace(overrideClassName) && !overrideClassName.Equals(className))
                        {
                            className = overrideClassName;
                            activityBehaviorInstance = null;
                        }
                    }
                }

                if (activityBehaviorInstance == null)
                {
                    activityBehaviorInstance = ActivityBehaviorInstance;
                }

                try
                {
                    activityBehaviorInstance.Execute(execution);
                }
                catch (BpmnError error)
                {
                    ErrorPropagation.PropagateError(error, execution);
                }
                catch (Exception e)
                {
                    if (!ErrorPropagation.MapException(e, execution, mapExceptions))
                    {
                        throw e;
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="activityBehavior"></param>
        /// <param name="flowNode"></param>
        protected internal virtual void ExecuteActivityBehavior(IActivityBehavior activityBehavior, FlowNode flowNode)
        {
            log.LogDebug($"Executing activityBehavior {activityBehavior.GetType()} on activity '{flowNode.Id}' with execution {execution.Id}");

            ProcessEngineConfigurationImpl processEngineConfiguration = Context.ProcessEngineConfiguration;

            if (processEngineConfiguration != null && processEngineConfiguration.EventDispatcher.Enabled)
            {
                processEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_STARTED, flowNode.Id, flowNode.Name, execution.Id, execution.ProcessInstanceId, execution.ProcessDefinitionId, flowNode));
            }

            try
            {
                activityBehavior.Execute(execution);
            }
            catch (Exception e)
            {
                throw new Exception($"{e.Message}", e);
            }
        }
示例#13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="boundaryEvents"></param>
        /// <param name="execution"></param>
        protected internal virtual void ExecuteBoundaryEvents(ICollection <BoundaryEvent> boundaryEvents, IExecutionEntity execution)
        {
            // The parent execution becomes a scope, and a child execution is created for each of the boundary events
            foreach (BoundaryEvent boundaryEvent in boundaryEvents)
            {
                if (CollectionUtil.IsEmpty(boundaryEvent.EventDefinitions) || (boundaryEvent.EventDefinitions[0] is CompensateEventDefinition))
                {
                    continue;
                }

                // A Child execution of the current execution is created to represent the boundary event being active
                IExecutionEntity childExecutionEntity = commandContext.ExecutionEntityManager.CreateChildExecution(execution);
                childExecutionEntity.ParentId           = execution.Id;
                childExecutionEntity.CurrentFlowElement = boundaryEvent;
                childExecutionEntity.IsScope            = false;

                IActivityBehavior boundaryEventBehavior = ((IActivityBehavior)boundaryEvent.Behavior);
                log.LogDebug($"Executing boundary event activityBehavior {boundaryEventBehavior.GetType()} with execution {childExecutionEntity.Id}");
                boundaryEventBehavior.Execute(childExecutionEntity);
            }
        }
示例#14
0
        public virtual void Execute(PvmExecutionImpl execution)
        {
            execution.ActivityInstanceDone();

            IActivityBehavior activityBehavior = ActivityBehaviorUtil.GetActivityBehavior(execution);

            if (activityBehavior is FlowNodeActivityBehavior)
            {
                FlowNodeActivityBehavior behavior = (FlowNodeActivityBehavior)activityBehavior;

                var activity           = execution.Activity;
                var activityInstanceId = execution.ActivityInstanceId;
                if (!ReferenceEquals(activityInstanceId, null))
                {
                    Log.DebugLeavesActivityInstance(execution, activityInstanceId);
                }

                try
                {
                    behavior.DoLeave(execution);
                }
                //catch (RuntimeException e)
                //{
                //    throw e;
                //}
                catch (System.Exception e)
                {
                    throw new PvmException(
                              "couldn't leave activity <" + activity.GetProperty("type") + " id=\"" + activity.Id +
                              "\" ...>: " + e.Message, e);
                }
            }
            else
            {
                throw new PvmException("Behavior of current activity is not an instance of " +
                                       typeof(FlowNodeActivityBehavior).Name + ". Execution " + execution);
            }
        }
示例#15
0
        /// <summary>
        ///
        /// </summary>
        protected override void RunOperation()
        {
            try
            {
                FlowElement currentFlowElement = GetCurrentFlowElement(execution);
                if (currentFlowElement is FlowNode node)
                {
                    IActivityBehavior activityBehavior = (IActivityBehavior)node.Behavior;
                    if (activityBehavior is ITriggerableActivityBehavior behavior)
                    {
                        if (currentFlowElement is BoundaryEvent)
                        {
                            commandContext.HistoryManager.RecordActivityStart(execution);
                        }

                        behavior.Trigger(execution, null, SignalData, false);

                        if (currentFlowElement is BoundaryEvent)
                        {
                            commandContext.HistoryManager.RecordActivityEnd(execution, null);
                        }
                    }
                    else
                    {
                        throw new ActivitiException("Invalid behavior: " + activityBehavior + " should implement " + typeof(ITriggerableActivityBehavior).FullName);
                    }
                }
                else
                {
                    throw new ActivitiException("Programmatic error: no current flow element found or invalid type: " + currentFlowElement + ". Halting.");
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, ex.Message);
                throw;
            }
        }
示例#16
0
        public override void Execute(IActivityExecution execution)
        {
            // If conditional events exist after the event based gateway they should be evaluated.
            // If a condition is satisfied the event based gateway should be left,
            // otherwise the event based gateway is a wait state
            var eventBasedGateway = (ActivityImpl)execution.Activity;

            foreach (var act in eventBasedGateway.EventActivities)
            {
                IActivityBehavior activityBehavior = act.ActivityBehavior;
                if (activityBehavior is IConditionalEventBehavior)
                {
                    var conditionalEventBehavior   = (IConditionalEventBehavior)activityBehavior;
                    var conditionalEventDefinition = conditionalEventBehavior.ConditionalEventDefinition;
                    if (conditionalEventDefinition.TryEvaluate(execution))
                    {
                        ((ExecutionEntity)execution).ExecuteEventHandlerActivity(
                            conditionalEventDefinition.ConditionalActivity);
                        return;
                    }
                }
            }
        }
示例#17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="flowNode"></param>
        protected internal virtual void ExecuteSynchronous(FlowNode flowNode)
        {
            commandContext.HistoryManager.RecordActivityStart(execution);

            // Execution listener: event 'start'
            if (CollectionUtil.IsNotEmpty(flowNode.ExecutionListeners))
            {
                ExecuteExecutionListeners(flowNode, BaseExecutionListenerFields.EVENTNAME_START);
            }

            // Execute any boundary events, sub process boundary events will be executed from the activity behavior
            if (!inCompensation && flowNode is Activity)
            { // Only activities can have boundary events
                IList <BoundaryEvent> boundaryEvents = ((Activity)flowNode).BoundaryEvents;
                if (CollectionUtil.IsNotEmpty(boundaryEvents))
                {
                    if (string.IsNullOrWhiteSpace(execution.Name))
                    {
                        execution.Name = flowNode.Name;
                    }
                    ExecuteBoundaryEvents(boundaryEvents, execution);
                }
            }

            // Execute actual behavior
            IActivityBehavior activityBehavior = (IActivityBehavior)flowNode.Behavior;

            if (activityBehavior != null)
            {
                ExecuteActivityBehavior(activityBehavior, flowNode);
            }
            else
            {
                log.LogDebug($"No activityBehavior on activity '{flowNode.Id}' with execution {execution.Id}");
                Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(execution, true);
            }
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="behaviorInstance"></param>
 /// <param name="execution"></param>
 public ActivityBehaviorInvocation(IActivityBehavior behaviorInstance, IExecutionEntity execution)
 {
     this.behaviorInstance = behaviorInstance;
     this.execution        = execution;
 }
示例#19
0
 public void SetActivityBehavior(IActivityBehavior coreActivityBehavior)
 {
     this.activityBehavior = coreActivityBehavior;
 }
 public ActivityBehaviorInvocation(IActivityBehavior behaviorInstance, IActivityExecution execution)
     : base(execution, null)
 {
     this._behaviorInstance = behaviorInstance;
     this._execution        = execution;
 }
示例#21
0
 public CustomActivityBehavior(IActivityBehavior activityBehavior)
 {
     _delegateActivityBehavior = activityBehavior;
 }
 public virtual ProcessDefinitionBuilder Behavior(IActivityBehavior activityBehaviour)
 {
     Activity.activityBehavior = activityBehaviour;
     return(this);
 }