use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class CompensationUtil method createEventScopeExecution.
/**
* creates an event scope for the given execution:
*
* create a new event scope execution under the parent of the given execution
* and move all event subscriptions to that execution.
*
* this allows us to "remember" the event subscriptions after finishing a
* scope
*/
public static void createEventScopeExecution(ExecutionEntity execution) {
// parent execution is a subprocess or a miBody
ActivityImpl activity = execution.getActivity();
ExecutionEntity scopeExecution = (ExecutionEntity) execution.findExecutionForFlowScope(activity.getFlowScope());
List<EventSubscriptionEntity> eventSubscriptions = execution.getCompensateEventSubscriptions();
if (eventSubscriptions.size() > 0 || hasCompensationEventSubprocess(activity)) {
ExecutionEntity eventScopeExecution = scopeExecution.createExecution();
eventScopeExecution.setActivity(execution.getActivity());
eventScopeExecution.activityInstanceStarting();
eventScopeExecution.enterActivityInstance();
eventScopeExecution.setActive(false);
eventScopeExecution.setConcurrent(false);
eventScopeExecution.setEventScope(true);
// copy local variables to eventScopeExecution by value. This way,
// the eventScopeExecution references a 'snapshot' of the local variables
Map<String, Object> variables = execution.getVariablesLocal();
for (Entry<String, Object> variable : variables.entrySet()) {
eventScopeExecution.setVariableLocal(variable.getKey(), variable.getValue());
}
// set event subscriptions to the event scope execution:
for (EventSubscriptionEntity eventSubscriptionEntity : eventSubscriptions) {
EventSubscriptionEntity newSubscription = EventSubscriptionEntity.createAndInsert(eventScopeExecution, EventType.COMPENSATE, eventSubscriptionEntity.getActivity());
newSubscription.setConfiguration(eventSubscriptionEntity.getConfiguration());
// use the original date
newSubscription.setCreated(eventSubscriptionEntity.getCreated());
}
// (ensuring they don't get removed when 'execution' gets removed)
for (PvmExecutionImpl childEventScopeExecution : execution.getEventScopeExecutions()) {
childEventScopeExecution.setParent(eventScopeExecution);
}
ActivityImpl compensationHandler = getEventScopeCompensationHandler(execution);
EventSubscriptionEntity eventSubscription = EventSubscriptionEntity.createAndInsert(scopeExecution, EventType.COMPENSATE, compensationHandler);
eventSubscription.setConfiguration(eventScopeExecution.getId());
}
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class AbstractBpmnActivityBehavior method propagateError.
protected void propagateError(String errorCode, String errorMessage, Exception origException, ActivityExecution execution) throws Exception {
ActivityExecutionHierarchyWalker walker = new ActivityExecutionHierarchyWalker(execution);
final ErrorDeclarationForProcessInstanceFinder errorDeclarationFinder = new ErrorDeclarationForProcessInstanceFinder(origException, errorCode, execution.getActivity());
ActivityExecutionMappingCollector activityExecutionMappingCollector = new ActivityExecutionMappingCollector(execution);
walker.addScopePreVisitor(errorDeclarationFinder);
walker.addExecutionPreVisitor(activityExecutionMappingCollector);
// map variables to super executions in the hierarchy of called process instances
walker.addExecutionPreVisitor(new OutputVariablesPropagator());
try {
walker.walkUntil(new ReferenceWalker.WalkCondition<ActivityExecutionTuple>() {
@Override
public boolean isFulfilled(ActivityExecutionTuple element) {
return errorDeclarationFinder.getErrorEventDefinition() != null || element == null;
}
});
} catch (Exception e) {
// separate the exception handling to support a fail-safe error propagation
throw new ErrorPropagationException(e);
}
PvmActivity errorHandlingActivity = errorDeclarationFinder.getErrorHandlerActivity();
// process the error
if (errorHandlingActivity == null) {
if (origException == null) {
if (Context.getCommandContext().getProcessEngineConfiguration().isEnableExceptionsAfterUnhandledBpmnError()) {
throw LOG.missingBoundaryCatchEventError(execution.getActivity().getId(), errorCode);
} else {
LOG.missingBoundaryCatchEvent(execution.getActivity().getId(), errorCode);
execution.end(true);
}
} else {
// throw original exception
throw origException;
}
} else {
ErrorEventDefinition errorDefinition = errorDeclarationFinder.getErrorEventDefinition();
PvmExecutionImpl errorHandlingExecution = activityExecutionMappingCollector.getExecutionForScope(errorHandlingActivity.getEventScope());
if (errorDefinition.getErrorCodeVariable() != null) {
errorHandlingExecution.setVariable(errorDefinition.getErrorCodeVariable(), errorCode);
}
if (errorDefinition.getErrorMessageVariable() != null) {
errorHandlingExecution.setVariable(errorDefinition.getErrorMessageVariable(), errorMessage);
}
errorHandlingExecution.executeActivity(errorHandlingActivity);
}
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class AbstractAtomicOperationCaseExecutionComplete method postTransitionNotification.
protected void postTransitionNotification(CmmnExecution execution) {
if (!execution.isCaseInstanceExecution()) {
execution.remove();
} else {
CmmnExecution superCaseExecution = execution.getSuperCaseExecution();
PvmExecutionImpl superExecution = execution.getSuperExecution();
if (superCaseExecution != null) {
TransferVariablesActivityBehavior behavior = (TransferVariablesActivityBehavior) getActivityBehavior(superCaseExecution);
behavior.transferVariables(execution, superCaseExecution);
superCaseExecution.complete();
} else if (superExecution != null) {
SubProcessActivityBehavior behavior = (SubProcessActivityBehavior) getActivityBehavior(superExecution);
try {
behavior.passOutputVariables(superExecution, execution);
} catch (RuntimeException e) {
LOG.completingSubCaseError(execution, e);
throw e;
} catch (Exception e) {
LOG.completingSubCaseError(execution, e);
throw LOG.completingSubCaseErrorException(execution, e);
}
// set sub case instance to null
superExecution.setSubCaseInstance(null);
try {
behavior.completed(superExecution);
} catch (RuntimeException e) {
LOG.completingSubCaseError(execution, e);
throw e;
} catch (Exception e) {
LOG.completingSubCaseError(execution, e);
throw LOG.completingSubCaseErrorException(execution, e);
}
}
execution.setSuperCaseExecution(null);
execution.setSuperExecution(null);
}
CmmnExecution parent = execution.getParent();
if (parent != null) {
CmmnActivityBehavior behavior = getActivityBehavior(parent);
if (behavior instanceof CmmnCompositeActivityBehavior) {
CmmnCompositeActivityBehavior compositeBehavior = (CmmnCompositeActivityBehavior) behavior;
compositeBehavior.handleChildCompletion(parent, execution);
}
}
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class PvmAtomicOperationActivityEnd method execute.
public void execute(PvmExecutionImpl execution) {
// restore activity instance id
if (execution.getActivityInstanceId() == null) {
execution.setActivityInstanceId(execution.getParentActivityInstanceId());
}
PvmActivity activity = execution.getActivity();
Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping = execution.createActivityExecutionMapping();
PvmExecutionImpl propagatingExecution = execution;
if (execution.isScope() && activity.isScope()) {
if (!LegacyBehavior.destroySecondNonScope(execution)) {
execution.destroy();
if (!execution.isConcurrent()) {
execution.remove();
propagatingExecution = execution.getParent();
propagatingExecution.setActivity(execution.getActivity());
}
}
}
propagatingExecution = LegacyBehavior.determinePropagatingExecutionOnEnd(propagatingExecution, activityExecutionMapping);
PvmScope flowScope = activity.getFlowScope();
// 1. flow scope = Process Definition
if (flowScope == activity.getProcessDefinition()) {
// 1.1 concurrent execution => end + tryPrune()
if (propagatingExecution.isConcurrent()) {
propagatingExecution.remove();
propagatingExecution.getParent().tryPruneLastConcurrentChild();
propagatingExecution.getParent().forceUpdate();
} else {
// 1.2 Process End
propagatingExecution.setEnded(true);
if (!propagatingExecution.isPreserveScope()) {
propagatingExecution.performOperation(PROCESS_END);
}
}
} else {
// 2. flowScope != process definition
PvmActivity flowScopeActivity = (PvmActivity) flowScope;
ActivityBehavior activityBehavior = flowScopeActivity.getActivityBehavior();
if (activityBehavior instanceof CompositeActivityBehavior) {
CompositeActivityBehavior compositeActivityBehavior = (CompositeActivityBehavior) activityBehavior;
// 2.1 Concurrent execution => composite behavior.concurrentExecutionEnded()
if (propagatingExecution.isConcurrent() && !LegacyBehavior.isConcurrentScope(propagatingExecution)) {
compositeActivityBehavior.concurrentChildExecutionEnded(propagatingExecution.getParent(), propagatingExecution);
} else {
// 2.2 Scope Execution => composite behavior.complete()
propagatingExecution.setActivity(flowScopeActivity);
compositeActivityBehavior.complete(propagatingExecution);
}
} else {
// activity behavior is not composite => this is unexpected
throw new ProcessEngineException("Expected behavior of composite scope " + activity + " to be a CompositeActivityBehavior but got " + activityBehavior);
}
}
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class PvmAtomicOperationActivityInstanceStart method eventNotificationsCompleted.
protected void eventNotificationsCompleted(PvmExecutionImpl execution) {
// hack around execution tree structure not being in sync with activity instance concept:
// if we start a scope activity, remember current activity instance in parent
PvmExecutionImpl parent = execution.getParent();
PvmActivity activity = execution.getActivity();
if (parent != null && execution.isScope() && activity.isScope() && canHaveChildScopes(execution)) {
parent.setActivityInstanceId(execution.getActivityInstanceId());
}
}
Aggregations