diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java index bb39be37456..234c0455509 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java @@ -77,7 +77,7 @@ public void internalAddWorkItem(InternalKogitoWorkItem workItem) { public InternalKogitoWorkItem getWorkItem(String workItemId) { InternalKogitoWorkItem workItem = workItems.get(workItemId); if (workItem == null) { - throw new WorkItemNotFoundException(workItemId); + throw new WorkItemNotFoundException("Work Item (" + workItemId + ") does not exist", workItemId); } return workItem; } @@ -92,7 +92,8 @@ public void internalExecuteWorkItem(InternalKogitoWorkItem workItem) { internalAddWorkItem(workItem); KogitoWorkItemHandler handler = getWorkItemHandler(workItem); WorkItemTransition transition = handler.startingTransition(Collections.emptyMap()); - transitionWorkItem(workItem, transition, true); + WorkItemTransition lastTransition = transitionWorkItem(workItem, transition); + cleanUp(workItem.getProcessInstance(), workItem, lastTransition); } public KogitoWorkItemHandler getWorkItemHandler(String workItemId) throws KogitoWorkItemHandlerNotFoundException { @@ -115,7 +116,7 @@ public KogitoWorkItemHandler getWorkItemHandler(InternalKogitoWorkItem workItem) public void internalAbortWorkItem(String workItemId) { InternalKogitoWorkItem workItem = getWorkItem(workItemId); KogitoWorkItemHandler handler = getWorkItemHandler(workItem); - transitionWorkItem(workItem, handler.abortTransition(workItem.getPhaseStatus()), false); + transitionWorkItem(workItem, handler.abortTransition(workItem.getPhaseStatus())); } @Override @@ -134,8 +135,8 @@ public void retryWorkItem(String workItemId, Map params) { } KogitoWorkItemHandler handler = getWorkItemHandler(workItem); WorkItemTransition transition = handler.startingTransition(Collections.emptyMap()); - transitionWorkItem(workItem, transition, true); - + WorkItemTransition lastTransition = transitionWorkItem(workItem, transition); + cleanUp(workItem.getProcessInstance(), workItem, lastTransition); } @Override @@ -143,10 +144,10 @@ public void completeWorkItem(String workItemId, Map data, Policy InternalKogitoWorkItem workItem = getWorkItem(workItemId); workItem.setState(KogitoWorkItem.COMPLETED); KogitoWorkItemHandler handler = getWorkItemHandler(workItem); - transitionWorkItem(workItem, handler.completeTransition(workItem.getPhaseStatus(), data, policies), false); + WorkItemTransition lastTransition = transitionWorkItem(workItem, handler.completeTransition(workItem.getPhaseStatus(), data, policies)); // process instance may have finished already KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); - processInstance.signalEvent("workItemCompleted", workItem); + cleanUp(processInstance, workItem, lastTransition); } @@ -155,11 +156,10 @@ public void abortWorkItem(String workItemId, Policy... policies) { InternalKogitoWorkItem workItem = getWorkItem(workItemId); workItem.setState(KogitoWorkItem.ABORTED); KogitoWorkItemHandler handler = getWorkItemHandler(workItemId); - transitionWorkItem(workItem, handler.abortTransition(workItem.getPhaseStatus(), policies), false); + WorkItemTransition lastTransition = transitionWorkItem(workItem, handler.abortTransition(workItem.getPhaseStatus(), policies)); // process instance may have finished already KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); - processInstance.signalEvent("workItemAborted", workItem); - + cleanUp(processInstance, workItem, lastTransition); } @Override @@ -182,11 +182,9 @@ public void internalCompleteWorkItem(InternalKogitoWorkItem workItem) { @Override public void transitionWorkItem(String workItemId, WorkItemTransition transition) { - InternalKogitoWorkItem workItem = workItems.get(workItemId); - if (workItem == null) { - throw new WorkItemNotFoundException("Work Item (" + workItemId + ") does not exist", workItemId); - } - transitionWorkItem(workItem, transition, true); + InternalKogitoWorkItem workItem = getWorkItem(workItemId); + WorkItemTransition lastTransition = transitionWorkItem(workItem, transition); + cleanUp(workItem.getProcessInstance(), workItem, lastTransition); } @Override @@ -194,7 +192,7 @@ public Collection getHandlerIds() { return this.workItemHandlers.keySet(); } - private void transitionWorkItem(InternalKogitoWorkItem workItem, WorkItemTransition transition, boolean signal) { + private WorkItemTransition transitionWorkItem(InternalKogitoWorkItem workItem, WorkItemTransition transition) { // work item may have been aborted KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); if (handler == null) { @@ -212,21 +210,26 @@ private void transitionWorkItem(InternalKogitoWorkItem workItem, WorkItemTransit this.eventSupport.fireAfterWorkItemTransition(workItem.getProcessInstance(), workItem, lastTransition, null); } - if (lastTransition.termination().isPresent()) { - internalRemoveWorkItem(workItem.getStringId()); - if (signal) { - switch (lastTransition.termination().get()) { - case COMPLETE: - workItem.setState(KogitoWorkItem.COMPLETED); - processInstance.signalEvent("workItemCompleted", workItem); - break; - case ABORT: - workItem.setState(KogitoWorkItem.ABORTED); - processInstance.signalEvent("workItemAborted", workItem); - break; - } - } + return lastTransition; + } + + private void cleanUp(KogitoProcessInstance processInstance, InternalKogitoWorkItem workItem, WorkItemTransition lastTransition) { + if (lastTransition.termination().isEmpty()) { + return; } + + switch (lastTransition.termination().get()) { + case COMPLETE: + workItem.setState(KogitoWorkItem.COMPLETED); + processInstance.signalEvent("workItemCompleted", workItem); + break; + case ABORT: + workItem.setState(KogitoWorkItem.ABORTED); + processInstance.signalEvent("workItemAborted", workItem); + break; + } + + internalRemoveWorkItem(workItem.getStringId()); } @Override diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java index 39d29374656..1a6e8f1d42e 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java @@ -169,7 +169,7 @@ protected void reconnect() { processInstance.setMetaData(KOGITO_PROCESS_INSTANCE, this); addCompletionEventListener(); - for (org.kie.api.runtime.process.NodeInstance nodeInstance : processInstance.getNodeInstances()) { + for (org.kie.api.runtime.process.NodeInstance nodeInstance : processInstance.getNodeInstances(true)) { if (nodeInstance instanceof WorkItemNodeInstance) { ((WorkItemNodeInstance) nodeInstance).internalRegisterWorkItem(); } @@ -197,7 +197,7 @@ protected void disconnect() { return; } - for (org.kie.api.runtime.process.NodeInstance nodeInstance : processInstance.getNodeInstances()) { + for (org.kie.api.runtime.process.NodeInstance nodeInstance : processInstance.getNodeInstances(true)) { if (nodeInstance instanceof WorkItemNodeInstance) { ((WorkItemNodeInstance) nodeInstance).internalRemoveWorkItem(); } diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerProcessListener.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerProcessListener.java index 05297f0fcf0..f1798035d46 100644 --- a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerProcessListener.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerProcessListener.java @@ -20,6 +20,7 @@ import org.kie.kogito.Model; import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.ProcessInstanceReadMode; import org.kie.kogito.process.Processes; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.usertask.UserTaskEventListener; @@ -45,16 +46,18 @@ public void onUserTaskState(UserTaskStateEvent event) { String processId = (String) event.getUserTaskInstance().getMetadata().get("ProcessId"); String processInstanceId = (String) event.getUserTaskInstance().getMetadata().get("ProcessInstanceId"); - ProcessInstance processInstance = processes.processById(processId).instances().findById(processInstanceId).orElse(null); + ProcessInstance processInstance = processes.processById(processId).instances().findById(processInstanceId, ProcessInstanceReadMode.MUTABLE).orElse(null); processInstance.updateWorkItem(event.getUserTaskInstance().getExternalReferenceId(), workItem -> { ((InternalKogitoWorkItem) workItem).setActualOwner(event.getUserTaskInstance().getActualOwner()); return workItem; }); // we check first that the work item is not fished to convey the signal Boolean notify = (Boolean) event.getUserTaskInstance().getMetadata().get(DefaultUserTaskLifeCycle.PARAMETER_NOTIFY); - if (notify == null || notify) { - processInstance.completeWorkItem(event.getUserTaskInstance().getExternalReferenceId(), event.getUserTaskInstance().getOutputs()); + if (notify != null && !notify) { + return; } + processInstance.completeWorkItem(event.getUserTaskInstance().getExternalReferenceId(), event.getUserTaskInstance().getOutputs()); + } }