1313package org .flowable .cmmn .engine .impl .deployer ;
1414
1515import java .util .Collection ;
16- import java .util .Collections ;
1716import java .util .LinkedHashMap ;
1817import java .util .LinkedHashSet ;
1918import java .util .List ;
2019import java .util .Map ;
21- import java .util .Objects ;
2220import java .util .Set ;
2321
2422import org .apache .commons .lang3 .StringUtils ;
25- import org .flowable .cmmn .converter .CmmnXmlConstants ;
2623import org .flowable .cmmn .engine .CmmnEngineConfiguration ;
2724import org .flowable .cmmn .engine .impl .parser .CmmnParseContext ;
2825import org .flowable .cmmn .engine .impl .parser .CmmnParseResult ;
3229import org .flowable .cmmn .engine .impl .persistence .entity .CmmnDeploymentEntity ;
3330import org .flowable .cmmn .engine .impl .persistence .entity .CmmnResourceEntity ;
3431import org .flowable .cmmn .engine .impl .persistence .entity .deploy .CaseDefinitionCacheEntry ;
35- import org .flowable .cmmn .engine .impl .util .CmmnCorrelationUtil ;
3632import org .flowable .cmmn .engine .impl .util .CommandContextUtil ;
3733import org .flowable .cmmn .model .Case ;
3834import org .flowable .cmmn .model .CmmnModel ;
39- import org .flowable .cmmn .model .ExtensionElement ;
4035import org .flowable .cmmn .validation .CaseValidator ;
4136import org .flowable .common .engine .api .FlowableException ;
4237import org .flowable .common .engine .api .delegate .Expression ;
4641import org .flowable .common .engine .impl .EngineDeployer ;
4742import org .flowable .common .engine .impl .assignment .CandidateUtil ;
4843import org .flowable .common .engine .impl .cfg .IdGenerator ;
44+ import org .flowable .common .engine .impl .context .Context ;
4945import org .flowable .common .engine .impl .el .ExpressionManager ;
46+ import org .flowable .common .engine .impl .interceptor .CommandContext ;
5047import org .flowable .common .engine .impl .persistence .deploy .DeploymentCache ;
5148import org .flowable .eventsubscription .service .EventSubscriptionService ;
49+ import org .flowable .eventsubscription .service .impl .persistence .entity .EventSubscriptionEntity ;
5250import org .flowable .identitylink .api .IdentityLinkType ;
5351import org .flowable .identitylink .service .IdentityLinkService ;
5452import org .flowable .identitylink .service .impl .persistence .entity .IdentityLinkEntity ;
@@ -193,39 +191,45 @@ protected void persistCaseDefinitions(CmmnParseResult parseResult) {
193191
194192 protected void updateEventSubscriptions (CmmnParseResult parseResult , Map <CaseDefinitionEntity , CaseDefinitionEntity > mapOfNewCaseDefinitionToPreviousVersion ) {
195193 EventSubscriptionService eventSubscriptionService = cmmnEngineConfiguration .getEventSubscriptionServiceConfiguration ().getEventSubscriptionService ();
196- for ( CaseDefinitionEntity caseDefinition : parseResult . getAllCaseDefinitions ()) {
194+ CommandContext commandContext = Context . getCommandContext ();
197195
196+ for (CaseDefinitionEntity caseDefinition : parseResult .getAllCaseDefinitions ()) {
197+ Case newCaseModel = parseResult .getCmmnCaseForCaseDefinition (caseDefinition );
198198 CaseDefinitionEntity previousCaseDefinition = mapOfNewCaseDefinitionToPreviousVersion .get (caseDefinition );
199+
199200 if (previousCaseDefinition != null ) {
200- if (isManualCorrelationSubscriptionConfiguration (parseResult , previousCaseDefinition )) {
201- // for a dynamic event registry start event, we don't remove the manually registered subscriptions, but rather update them to the newest
202- // case definition, if required
203- String startEventType = getCaseModel (parseResult , previousCaseDefinition ).getPrimaryCase ().getStartEventType ();
204- updateOldEventSubscriptions (previousCaseDefinition , caseDefinition , startEventType );
205- } else {
206- // for a static event registry start event, we delete the old subscription and will later create a new one
207- eventSubscriptionService .deleteEventSubscriptionsForScopeDefinitionIdAndTypeAndNullScopeId (previousCaseDefinition .getId (), ScopeTypes .CMMN );
201+ Case previousCaseModel = getCaseModel (parseResult , previousCaseDefinition ).getPrimaryCase ();
202+ Set <String > obsoleteEventTypes = new LinkedHashSet <>();
203+
204+ for (Object handler : previousCaseModel .getStartLifecycleHandlers ()) {
205+ if (handler instanceof CaseDefinitionStartLifecycleHandler lifecycleHandler ) {
206+ lifecycleHandler .undeploy (new CaseDefinitionStartUndeployContext (
207+ previousCaseDefinition , caseDefinition , previousCaseModel ,
208+ cmmnEngineConfiguration , commandContext , obsoleteEventTypes ));
209+ }
210+ }
211+
212+ if (!obsoleteEventTypes .isEmpty ()) {
213+ deleteObsoleteEventSubscriptions (previousCaseDefinition , obsoleteEventTypes , eventSubscriptionService );
208214 }
209215 }
210216
211- // create new subscriptions, but only for static event registry start events
212- Case caseModel = parseResult .getCmmnCaseForCaseDefinition (caseDefinition );
213- String startEventType = caseModel .getStartEventType ();
214- if (startEventType != null && !isManualCorrelationSubscriptionConfiguration (parseResult , caseDefinition )) {
215- eventSubscriptionService .createEventSubscriptionBuilder ()
216- .eventType (startEventType )
217- .configuration (getEventCorrelationKey (caseModel ))
218- .scopeDefinitionId (caseDefinition .getId ())
219- .scopeType (ScopeTypes .CMMN )
220- .tenantId (caseDefinition .getTenantId ())
221- .create ();
217+ for (Object handler : newCaseModel .getStartLifecycleHandlers ()) {
218+ if (handler instanceof CaseDefinitionStartLifecycleHandler lifecycleHandler ) {
219+ lifecycleHandler .deploy (new CaseDefinitionStartDeployContext (
220+ caseDefinition , newCaseModel , cmmnEngineConfiguration , commandContext ));
221+ }
222222 }
223223 }
224224 }
225225
226- protected void updateOldEventSubscriptions (CaseDefinitionEntity previousCaseDefinition , CaseDefinitionEntity caseDefinition , String eventType ) {
227- CommandContextUtil .getCmmnEngineConfiguration ().getEventSubscriptionServiceConfiguration ().getEventSubscriptionService ().updateEventSubscriptionScopeDefinitionId (
228- previousCaseDefinition .getId (), caseDefinition .getId (), eventType , caseDefinition .getKey (), null );
226+ protected void deleteObsoleteEventSubscriptions (CaseDefinitionEntity previousCaseDefinition , Collection <String > eventTypes ,
227+ EventSubscriptionService eventSubscriptionService ) {
228+ List <EventSubscriptionEntity > subscriptionsToDelete = eventSubscriptionService .findEventSubscriptionsByTypesAndScopeDefinitionId (
229+ eventTypes , previousCaseDefinition .getId (), ScopeTypes .CMMN , previousCaseDefinition .getTenantId ());
230+ for (EventSubscriptionEntity subscription : subscriptionsToDelete ) {
231+ eventSubscriptionService .deleteEventSubscription (subscription );
232+ }
229233 }
230234
231235 protected CmmnModel getCaseModel (CmmnParseResult parseResult , CaseDefinitionEntity caseDefinition ) {
@@ -237,20 +241,6 @@ protected CmmnModel getCaseModel(CmmnParseResult parseResult, CaseDefinitionEnti
237241 return caseModel ;
238242 }
239243
240- protected boolean isManualCorrelationSubscriptionConfiguration (CmmnParseResult parseResult , CaseDefinitionEntity caseDefinition ) {
241- CmmnModel caseModel = getCaseModel (parseResult , caseDefinition );
242- List <ExtensionElement > correlationCfgExtensions = caseModel .getPrimaryCase ().getExtensionElements ()
243- .getOrDefault (CmmnXmlConstants .START_EVENT_CORRELATION_CONFIGURATION , Collections .emptyList ());
244- if (!correlationCfgExtensions .isEmpty ()) {
245- return Objects .equals (correlationCfgExtensions .get (0 ).getElementText (), CmmnXmlConstants .START_EVENT_CORRELATION_MANUAL );
246- }
247- return false ;
248- }
249-
250- protected String getEventCorrelationKey (Case caseModel ) {
251- return CmmnCorrelationUtil .getCorrelationKey (CmmnXmlConstants .ELEMENT_EVENT_CORRELATION_PARAMETER , CommandContextUtil .getCommandContext (), caseModel );
252- }
253-
254244 protected void makeCaseDefinitionsConsistentWithPersistedVersions (CmmnParseResult parseResult ) {
255245 for (CaseDefinitionEntity caseDefinition : parseResult .getAllCaseDefinitions ()) {
256246 CaseDefinitionEntity persistedCaseDefinition = getPersistedInstanceOfCaseDefinition (caseDefinition );
0 commit comments