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); } }
/// <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); } } } }
/// <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); } }
// 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); }
/// <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)); }
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"); } }
// 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"); } }
// 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"); } }
/// <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}"); } }
// 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; } } } }
/// <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); } }
/// <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); } }
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); } }
/// <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; } }
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; } } } }
/// <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; }
public void SetActivityBehavior(IActivityBehavior coreActivityBehavior) { this.activityBehavior = coreActivityBehavior; }
public ActivityBehaviorInvocation(IActivityBehavior behaviorInstance, IActivityExecution execution) : base(execution, null) { this._behaviorInstance = behaviorInstance; this._execution = execution; }
public CustomActivityBehavior(IActivityBehavior activityBehavior) { _delegateActivityBehavior = activityBehavior; }
public virtual ProcessDefinitionBuilder Behavior(IActivityBehavior activityBehaviour) { Activity.activityBehavior = activityBehaviour; return(this); }