Class LegacyBehavior
java.lang.Object
org.camunda.bpm.engine.impl.pvm.runtime.LegacyBehavior
This class encapsulates legacy runtime behavior for the process engine.
Since 7.3 the behavior of certain bpmn elements has changed slightly.
1. Some elements which did not used to be scopes are now scopes:
- Sequential multi instance Embedded Subprocess: is now a scope, used to be non-scope.
- Event subprocess: is now a scope, used to be non-scope.
- Since:
- 7.3
- Author:
- Daniel Meyer
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected static booleanareEqualEventSubscriptions(EventSubscriptionEntity subscription1, EventSubscriptionEntity subscription2) Checks if the parameters are the same apart from the execution idstatic voidcancelConcurrentScope(PvmExecutionImpl execution, PvmActivity cancelledScopeActivity) Cancels an execution which is both concurrent and scope.static Map<ScopeImpl,PvmExecutionImpl> createActivityExecutionMapping(List<PvmExecutionImpl> scopeExecutions, List<ScopeImpl> scopes) Creates an activity execution mapping, when the scope hierarchy and the execution hierarchy are out of sync.static voidcreateMissingHistoricVariables(PvmExecutionImpl execution) See #CAM-10978 Use case process instance withasyncBeforestartEvent After unifying the history variable's creation
The following changed:
* variables will receive theprocessInstanceIdasactivityInstanceIdin such cases (previously was the startEvent id)
* historic details have newinitialproperty to track initial variables that process is started with
The jobs created prior7.13and not executed before do not have historic information of variables.static voiddestroyConcurrentScope(PvmExecutionImpl execution) Destroys a concurrent scope Execution.static booleandestroySecondNonScope(PvmExecutionImpl execution) Destroy an execution for an activity that was previously not a scope and now is (e.g.static PvmExecutionImpldeterminePropagatingExecutionOnEnd(PvmExecutionImpl propagatingExecution, Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping) Tolerates the broken execution trees fixed with CAM-3727 where there may be more ancestor scope executions than ancestor flow scopes; In that case, the argument execution is removed, the parent execution of the argument is returned such that one level of mismatch is corrected.protected static voidensureConcurrent(PvmExecutionImpl execution) protected static voidensureConcurrentScope(PvmExecutionImpl execution) protected static voidensureScope(PvmExecutionImpl execution) static booleaneventSubprocessComplete(ActivityExecution scopeExecution) static booleaneventSubprocessConcurrentChildExecutionEnded(ActivityExecution scopeExecution, ActivityExecution endedExecution) protected static PvmExecutionImplstatic PvmExecutionImplgetScopeExecution(ScopeImpl scope, Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping) In case the process instance was migrated from a previous version, activities which are now parsed as scopes do not have scope executions.protected static ScopeImplgetTopMostScope(List<ScopeImpl> scopes) static booleanhasInvalidIntermediaryActivityId(PvmExecutionImpl execution) In general, only leaf executions have activity ids.protected static booleanprotected static booleanisAsync(ActivityImpl activity) protected static booleanisAsyncJobDefinition(JobDefinitionEntity jobDefinition) static booleanisCompensationThrowing(PvmExecutionImpl execution) static booleanisCompensationThrowing(PvmExecutionImpl execution, Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping) Returns true if the given execution is in a compensation-throwing activity but there is no dedicated scope execution in the given mapping.static booleanisConcurrentScope(PvmExecutionImpl propagatingExecution) Concurrent + scope executions are legacy and could occur in processes with non-interrupting boundary events or event subprocessesprotected static booleanisLegacyAsyncAtMultiInstance(PvmExecutionImpl execution) This returns true only if the provided execution has reached its wait state in a legacy engine version, because only in that case, it can be async and waiting at the inner activity wrapped by the miBody.protected static booleanisLegacyBehaviorRequired(ActivityExecution scopeExecution) This methodprotected static booleanisMultiInstanceInCompensation(ActivityImpl activity, PvmExecutionImpl scopeExecutionCandidate) static voidmigrateMultiInstanceJobDefinitions(ProcessDefinitionEntity processDefinition, List<JobDefinitionEntity> jobDefinitions) When deploying an async job definition for an activity wrapped in an miBody, set the activity id to the miBody except the wrapped activity is marked as async.static voidparseCancelBoundaryEvent(ActivityImpl activity) static voidpruneConcurrentScope(PvmExecutionImpl execution) Prunes a concurrent scope.static voidRemove all entries for legacy non-scopes given that the assigned scope execution is also responsible for another scopestatic voidremoveLegacySubscriptionOnParent(ExecutionEntity execution, EventSubscriptionEntity eventSubscription) Required for migrating active sequential MI receive tasks.static voidrepairMultiInstanceAsyncJob(ExecutionEntity execution) When executing an async job for an activity wrapped in an miBody, set the execution to the miBody except the wrapped activity is marked as async.static voidrepairParentRelationships(Collection<ActivityInstanceImpl> values, String processInstanceId) This is relevant forGetActivityInstanceCmdwhere in case of legacy multi-instance execution trees, the default algorithm omits multi-instance activity instances.static booleansignalCancelBoundaryEvent(String signalName) With prior versions, the boundary event was already executed when compensation was performed; Thus, after compensation completes, the execution is signalled waiting at the boundary event.protected static <T> booleanvaluesEqual(T value1, T value2) protected static booleanwasNoScope(ActivityImpl activity, PvmExecutionImpl scopeExecutionCandidate) Determines whether the given scope was a scope in previous versionsprotected static booleanwasNoScope72(ActivityImpl activity) protected static booleanwasNoScope73(ActivityImpl activity, PvmExecutionImpl scopeExecutionCandidate)
-
Constructor Details
-
LegacyBehavior
public LegacyBehavior()
-
-
Method Details
-
pruneConcurrentScope
Prunes a concurrent scope. This can only happen if (a) the process instance has been migrated from a previous version to a new version of the process engine This is an inverse operation to#createConcurrentScope(PvmExecutionImpl). See: javadoc of this class for note about concurrent scopes.- Parameters:
execution-
-
cancelConcurrentScope
public static void cancelConcurrentScope(PvmExecutionImpl execution, PvmActivity cancelledScopeActivity) Cancels an execution which is both concurrent and scope. This can only happen if (a) the process instance has been migrated from a previous version to a new version of the process engine See: javadoc of this class for note about concurrent scopes.- Parameters:
execution- the concurrent scope execution to destroycancelledScopeActivity- the activity that cancels the execution; it must hold that cancellingActivity's event scope is the scope the execution is responsible for
-
destroyConcurrentScope
Destroys a concurrent scope Execution. This can only happen if (a) the process instance has been migrated from a previous version to a 7.3+ version of the process engine See: javadoc of this class for note about concurrent scopes.- Parameters:
execution- the execution to destroy
-
eventSubprocessComplete
-
eventSubprocessConcurrentChildExecutionEnded
public static boolean eventSubprocessConcurrentChildExecutionEnded(ActivityExecution scopeExecution, ActivityExecution endedExecution) -
destroySecondNonScope
Destroy an execution for an activity that was previously not a scope and now is (e.g. event subprocess) -
isLegacyBehaviorRequired
This method- Parameters:
scopeExecution-- Returns:
-
getScopeExecution
public static PvmExecutionImpl getScopeExecution(ScopeImpl scope, Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping) In case the process instance was migrated from a previous version, activities which are now parsed as scopes do not have scope executions. Use the flow scopes of these activities in order to find their execution. - For an event subprocess this is the scope execution of the scope in which the event subprocess is embeded in - For a multi instance sequential subprocess this is the multi instace scope body.- Parameters:
scope-activityExecutionMapping-- Returns:
-
ensureConcurrentScope
-
ensureConcurrent
-
ensureScope
-
createActivityExecutionMapping
public static Map<ScopeImpl,PvmExecutionImpl> createActivityExecutionMapping(List<PvmExecutionImpl> scopeExecutions, List<ScopeImpl> scopes) Creates an activity execution mapping, when the scope hierarchy and the execution hierarchy are out of sync.- Parameters:
scopeExecutions-scopes-- Returns:
-
wasNoScope
protected static boolean wasNoScope(ActivityImpl activity, PvmExecutionImpl scopeExecutionCandidate) Determines whether the given scope was a scope in previous versions -
wasNoScope72
-
wasNoScope73
protected static boolean wasNoScope73(ActivityImpl activity, PvmExecutionImpl scopeExecutionCandidate) -
isMultiInstanceInCompensation
protected static boolean isMultiInstanceInCompensation(ActivityImpl activity, PvmExecutionImpl scopeExecutionCandidate) -
isLegacyAsyncAtMultiInstance
This returns true only if the provided execution has reached its wait state in a legacy engine version, because only in that case, it can be async and waiting at the inner activity wrapped by the miBody. In versions >= 7.3, the execution would reference the multi-instance body instead. -
determinePropagatingExecutionOnEnd
public static PvmExecutionImpl determinePropagatingExecutionOnEnd(PvmExecutionImpl propagatingExecution, Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping) Tolerates the broken execution trees fixed with CAM-3727 where there may be more ancestor scope executions than ancestor flow scopes; In that case, the argument execution is removed, the parent execution of the argument is returned such that one level of mismatch is corrected. Note that this does not necessarily skip the correct scope execution, since the broken parent-child relationships may be anywhere in the tree (e.g. consider a non-interrupting boundary event followed by a subprocess (i.e. scope), when the subprocess ends, we would skip the subprocess's execution). -
isConcurrentScope
Concurrent + scope executions are legacy and could occur in processes with non-interrupting boundary events or event subprocesses -
removeLegacySubscriptionOnParent
public static void removeLegacySubscriptionOnParent(ExecutionEntity execution, EventSubscriptionEntity eventSubscription) Required for migrating active sequential MI receive tasks. These activities were formerly not scope, but are now. This has the following implications:
Before migration:
- the event subscription is attached to the miBody scope execution
After migration:
- a new subscription is created for every instance
- the new subscription is attached to a dedicated scope execution as a child of the miBody scope execution
Thus, this method removes the subscription on the miBody scope
-
areEqualEventSubscriptions
protected static boolean areEqualEventSubscriptions(EventSubscriptionEntity subscription1, EventSubscriptionEntity subscription2) Checks if the parameters are the same apart from the execution id -
valuesEqual
protected static <T> boolean valuesEqual(T value1, T value2) -
removeLegacyNonScopesFromMapping
Remove all entries for legacy non-scopes given that the assigned scope execution is also responsible for another scope -
getTopMostScope
-
repairParentRelationships
public static void repairParentRelationships(Collection<ActivityInstanceImpl> values, String processInstanceId) This is relevant forGetActivityInstanceCmdwhere in case of legacy multi-instance execution trees, the default algorithm omits multi-instance activity instances. -
migrateMultiInstanceJobDefinitions
public static void migrateMultiInstanceJobDefinitions(ProcessDefinitionEntity processDefinition, List<JobDefinitionEntity> jobDefinitions) When deploying an async job definition for an activity wrapped in an miBody, set the activity id to the miBody except the wrapped activity is marked as async. Background: in <= 7.2 async job definitions were created for the inner activity, although the semantics are that they are executed before the miBody is entered -
isAsync
-
isAsyncJobDefinition
-
isActivityWrappedInMultiInstanceBody
-
repairMultiInstanceAsyncJob
When executing an async job for an activity wrapped in an miBody, set the execution to the miBody except the wrapped activity is marked as async. Background: in <= 7.2 async jobs were created for the inner activity, although the semantics are that they are executed before the miBody is entered -
signalCancelBoundaryEvent
With prior versions, the boundary event was already executed when compensation was performed; Thus, after compensation completes, the execution is signalled waiting at the boundary event. -
parseCancelBoundaryEvent
- See Also:
-
hasInvalidIntermediaryActivityId
In general, only leaf executions have activity ids.
Exception to that rule: compensation throwing executions.
Legacy exception (<= 7.2) to that rule: miBody executions and parallel gateway executions
- Returns:
- true, if the argument is not a leaf and has an invalid (i.e. legacy) non-null activity id
-
isCompensationThrowing
public static boolean isCompensationThrowing(PvmExecutionImpl execution, Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping) Returns true if the given execution is in a compensation-throwing activity but there is no dedicated scope execution in the given mapping. -
isCompensationThrowing
-
findCompensationThrowingAncestorExecution
protected static PvmExecutionImpl findCompensationThrowingAncestorExecution(PvmExecutionImpl execution) -
createMissingHistoricVariables
See #CAM-10978 Use case process instance withasyncBeforestartEvent After unifying the history variable's creation
The following changed:
* variables will receive theprocessInstanceIdasactivityInstanceIdin such cases (previously was the startEvent id)
* historic details have newinitialproperty to track initial variables that process is started with
The jobs created prior7.13and not executed before do not have historic information of variables. This method takes care of that.
-