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; List <ICompensateEventSubscriptionEntity> eventSubscriptions = new List <ICompensateEventSubscriptionEntity>(); if (!string.IsNullOrWhiteSpace(activityRef)) { // If an activity ref is provided, only that activity is compensated eventSubscriptions.AddRange(eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, activityRef)); } else { eventSubscriptions.AddRange(eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, null)); // If no activity ref is provided, it is broadcast to the current sub process / process instance //IFlowElementsContainer process = ProcessDefinitionUtil.GetProcess(execution.ProcessDefinitionId); //IFlowElementsContainer flowElementsContainer; //if (throwEvent.SubProcess == null) //{ // flowElementsContainer = process; //} //else //{ // flowElementsContainer = throwEvent.SubProcess; //} ////if (flowElementsContainer != process) ////{ //// foreach (FlowElement flowElement in process.FlowElements) //// { //// if (flowElement is Activity) //// { //// IList<ICompensateEventSubscriptionEntity> compensateEvents = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, flowElement.Id); //// eventSubscriptions.AddRange(compensateEvents); //// } //// } ////} //foreach (FlowElement flowElement in flowElementsContainer.FlowElements) //{ // if (flowElement is Activity) // { // IList<ICompensateEventSubscriptionEntity> compensateEvents = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, flowElement.Id); // eventSubscriptions.AddRange(compensateEvents); // } //} } Leave(execution); if (eventSubscriptions.Count > 0) { // TODO: implement async (waitForCompletion=false in bpmn) ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false); } }