From 07a2fe422dfa6c2cefdfb658e44b45fc9365b3d0 Mon Sep 17 00:00:00 2001 From: Roberto Oliveira Date: Thu, 3 Oct 2024 09:02:37 -0400 Subject: [PATCH 01/15] [incubator-kie-issues#1467] Deleting reproducible profile and its invocation (#3663) * [incubator-kie-issues#1467] Deleting reproducible profile and its invocation * [incubator-kie-issues#1467] Hardcoding reference to twin PR/pull-request-config.yaml * [incubator-kie-issues#1467] Update hardcoded reference to twin PR/pull-request-config.yaml * [incubator-kie-issues#1467] Update hardcoded reference to twin PR/pull-request-config.yaml * [incubator-kie-issues#1467] Update hardcoded reference to twin PR/pull-request-config.yaml * [incubator-kie-issues#1467] Update hardcoded reference to twin PR/pull-request-config.yaml * [incubator-kie-issues#1467] Update hardcoded reference to twin PR/pull-request-config.yaml * [incubator-kie-issues#1467] Restoring reference to pull-request-config.yaml --------- Co-authored-by: Gabriele-Cardosi # Conflicts: # .github/workflows/pr-kogito-runtimes.yml --- pom.xml | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/pom.xml b/pom.xml index 51c1a4f9b58..d4a05d4f29f 100644 --- a/pom.xml +++ b/pom.xml @@ -165,43 +165,4 @@ springboot - - - reproducible-build - - - reproducible - - - - - - org.apache.maven.plugins - maven-artifact-plugin - - - check-buildplan - - check-buildplan - - - validate - - - compare - - compare - - - install - - - - - - - - From c7db0512512aa22e326264864d2813f629763530 Mon Sep 17 00:00:00 2001 From: Abhiram Gundala <164050036+Abhitocode@users.noreply.github.com> Date: Mon, 16 Sep 2024 02:30:08 -0400 Subject: [PATCH 02/15] [incubator-kie-issues-1131] v7 migration to code generation (#3610) --- .../org/jbpm/bpmn2/IntermediateEventTest.java | 742 ++++++++++-------- 1 file changed, 404 insertions(+), 338 deletions(-) diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java index 1d24ef1aa49..00c1c45d721 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java @@ -41,8 +41,20 @@ import org.jbpm.bpmn2.event.BoundaryTimerCycleISOVariableProcess; import org.jbpm.bpmn2.handler.ReceiveTaskHandler; import org.jbpm.bpmn2.handler.SendTaskHandler; +import org.jbpm.bpmn2.intermediate.BoundarySignalEventOnTaskModel; +import org.jbpm.bpmn2.intermediate.BoundarySignalEventOnTaskProcess; +import org.jbpm.bpmn2.intermediate.EventBasedSplit2Model; +import org.jbpm.bpmn2.intermediate.EventBasedSplit2Process; +import org.jbpm.bpmn2.intermediate.EventBasedSplit4Model; +import org.jbpm.bpmn2.intermediate.EventBasedSplit4Process; +import org.jbpm.bpmn2.intermediate.EventBasedSplitModel; +import org.jbpm.bpmn2.intermediate.EventBasedSplitProcess; import org.jbpm.bpmn2.intermediate.EventSubprocessErrorSignalEmbeddedModel; import org.jbpm.bpmn2.intermediate.EventSubprocessErrorSignalEmbeddedProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageWithRefModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageWithRefProcess; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageWithTransformationModel; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageWithTransformationProcess; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventSignal2Model; @@ -51,19 +63,41 @@ import org.jbpm.bpmn2.intermediate.IntermediateCatchEventSignalProcess; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventSignalWithTransformationModel; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventSignalWithTransformationProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycle1Model; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycle1Process; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycle2Model; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycle2Process; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycle3Model; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycle3Process; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycleCronModel; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycleCronProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycleISOModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerCycleISOProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDateISOModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDateISOProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationISOModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationISOProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationProcess; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationWithErrorModel; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationWithErrorProcess; import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationWithErrorProcessInstance; import org.jbpm.bpmn2.intermediate.IntermediateCatchSignalBetweenUserTasksModel; import org.jbpm.bpmn2.intermediate.IntermediateCatchSignalBetweenUserTasksProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchSignalSingleModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchSignalSingleProcess; +import org.jbpm.bpmn2.intermediate.IntermediateLinkEventModel; +import org.jbpm.bpmn2.intermediate.IntermediateLinkEventProcess; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageModel; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageProcess; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageWithTransformationModel; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageWithTransformationProcess; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventNoneModel; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventNoneProcess; +import org.jbpm.bpmn2.intermediate.LinkEventCompositeProcessModel; +import org.jbpm.bpmn2.intermediate.LinkEventCompositeProcessProcess; +import org.jbpm.bpmn2.intermediate.SignalBoundaryEventInterruptingModel; +import org.jbpm.bpmn2.intermediate.SignalBoundaryEventInterruptingProcess; import org.jbpm.bpmn2.loop.MultiInstanceLoopBoundaryTimerModel; import org.jbpm.bpmn2.loop.MultiInstanceLoopBoundaryTimerProcess; import org.jbpm.bpmn2.loop.MultiInstanceLoopCharacteristicsProcessSequentialModel; @@ -87,6 +121,16 @@ import org.jbpm.bpmn2.subprocess.EventSubprocessSignalWithTransformationModel; import org.jbpm.bpmn2.subprocess.EventSubprocessSignalWithTransformationProcess; import org.jbpm.bpmn2.test.RequirePersistence; +import org.jbpm.bpmn2.timer.TimerBoundaryEventCycle1Model; +import org.jbpm.bpmn2.timer.TimerBoundaryEventCycle1Process; +import org.jbpm.bpmn2.timer.TimerBoundaryEventCycle2Model; +import org.jbpm.bpmn2.timer.TimerBoundaryEventCycle2Process; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingModel; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingOnTaskCancelTimerModel; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingOnTaskCancelTimerProcess; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingOnTaskModel; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingOnTaskProcess; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingProcess; import org.jbpm.process.core.datatype.impl.type.StringDataType; import org.jbpm.process.instance.event.listeners.RuleAwareProcessEventListener; import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; @@ -105,6 +149,7 @@ import org.kie.api.event.process.ProcessStartedEvent; import org.kie.api.runtime.rule.FactHandle; import org.kie.kogito.Application; +import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.event.impl.MessageProducer; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; @@ -188,25 +233,28 @@ public void testBoundaryTimerCycleISOVariable() { } @Test - public void testSignalBoundaryEvent() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-BoundarySignalEventOnTask.bpmn", - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventSignal.bpmn2"); + public void testSignalBoundaryEvent() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new TestWorkItemHandler()); - TestWorkItemHandler handler = new TestWorkItemHandler(); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); - KogitoProcessInstance processInstance = kruntime.startProcess("BoundarySignalEventOnTask"); + org.kie.kogito.process.Process signalEventOnTaskProcess = BoundarySignalEventOnTaskProcess.newProcess(app); + org.kie.kogito.process.Process throwEventSignalProcess = IntermediateThrowEventSignalProcess.newProcess(app); - Set> eventDescriptions = processInstance.getEventDescriptions(); + org.kie.kogito.process.ProcessInstance taskProcessInstance = signalEventOnTaskProcess.createInstance(signalEventOnTaskProcess.createModel()); + taskProcessInstance.start(); + + Set> eventDescriptions = taskProcessInstance.events(); assertThat(eventDescriptions).hasSize(2).extracting("event").contains("MySignal"); assertThat(eventDescriptions).extracting("eventType").contains("signal"); - assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId()); + assertThat(eventDescriptions).extracting("processInstanceId").contains(taskProcessInstance.id()); assertThat(eventDescriptions).filteredOn("eventType", "signal").hasSize(1).extracting("properties", Map.class) .anyMatch(m -> m.containsKey("AttachedToID") && m.containsKey("AttachedToName")); - KogitoProcessInstance processInstance2 = kruntime.startProcess("IntermediateThrowEventSignal"); - assertProcessInstanceFinished(processInstance2, kruntime); + org.kie.kogito.process.ProcessInstance signalProcessInstance = throwEventSignalProcess.createInstance(throwEventSignalProcess.createModel()); + signalProcessInstance.start(); - assertProcessInstanceFinished(processInstance, kruntime); + assertThat(signalProcessInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); + assertThat(taskProcessInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test @@ -220,6 +268,7 @@ public void testSignalBoundaryNonEffectiveEvent() throws Exception { kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); kruntime.getProcessEventManager().addEventListener(new DefaultKogitoProcessEventListener() { + @Override public void afterNodeLeft(ProcessNodeLeftEvent event) { // BoundaryEventNodeInstance @@ -243,29 +292,31 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { } @Test - public void testSignalBoundaryEventOnTask() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-BoundarySignalEventOnTask.bpmn"); + public void testSignalBoundaryEventOnTask() { + Application app = ProcessTestHelper.newApplication(); + TestWorkItemHandler handler = new TestWorkItemHandler(); + ProcessTestHelper.registerHandler(app, "Human Task", handler); + ProcessTestHelper.registerProcessEventListener(app, LOGGING_EVENT_LISTENER); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new TestWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(LOGGING_EVENT_LISTENER); - KogitoProcessInstance processInstance = kruntime.startProcess("BoundarySignalEventOnTask"); + org.kie.kogito.process.Process processDefinition = BoundarySignalEventOnTaskProcess.newProcess(app); + BoundarySignalEventOnTaskModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); - Set> eventDescriptions = processInstance.getEventDescriptions(); + Set> eventDescriptions = instance.events(); assertThat(eventDescriptions).hasSize(2).extracting("event").contains("MySignal", "workItemCompleted"); assertThat(eventDescriptions).extracting("eventType").contains("signal", "workItem"); assertThat(eventDescriptions).extracting("nodeId").contains("BoundaryEvent_2", "UserTask_1"); - assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId()); + assertThat(eventDescriptions).extracting("processInstanceId").contains(instance.id()); assertThat(eventDescriptions).filteredOn("eventType", "signal").hasSize(1).extracting("properties", Map.class) .anyMatch(m -> m.containsKey("AttachedToID") && m.containsKey("AttachedToName")); assertThat(eventDescriptions).filteredOn("eventType", "signal").hasSize(1).extracting("nodeInstanceId") .containsOnlyNulls(); - assertThat(eventDescriptions).filteredOn("eventType", "workItem").hasSize(1).extracting("nodeInstanceId") .doesNotContainNull(); - kruntime.signalEvent("MySignal", "value"); - assertProcessInstanceFinished(processInstance, kruntime); - + instance.send(Sig.of("MySignal", "value")); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test @@ -287,180 +338,178 @@ public void testSignalBoundaryEventOnTaskWithSignalName() throws Exception { } @Test - public void testSignalBoundaryEventOnTaskComplete() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-BoundarySignalEventOnTask.bpmn"); - + public void testSignalBoundaryEventOnTaskComplete() { + Application app = ProcessTestHelper.newApplication(); TestWorkItemHandler handler = new TestWorkItemHandler(); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); - kruntime.getProcessEventManager().addEventListener(LOGGING_EVENT_LISTENER); - KogitoProcessInstance processInstance = kruntime.startProcess("BoundarySignalEventOnTask"); - kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), null); - kruntime.signalEvent("MySignal", "value"); - kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), null); - assertProcessInstanceFinished(processInstance, kruntime); - + ProcessTestHelper.registerHandler(app, "Human Task", handler); + ProcessTestHelper.registerProcessEventListener(app, LOGGING_EVENT_LISTENER); + org.kie.kogito.process.Process processDefinition = BoundarySignalEventOnTaskProcess.newProcess(app); + BoundarySignalEventOnTaskModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + KogitoWorkItem workItem = handler.getWorkItem(); + instance.completeWorkItem(workItem.getStringId(), null); + workItem = handler.getWorkItem(); + instance.completeWorkItem(workItem.getStringId(), null); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testSignalBoundaryEventInterrupting() throws Exception { - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-SignalBoundaryEventInterrupting.bpmn2"); - - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("SignalBoundaryEventInterrupting"); - assertProcessInstanceActive(processInstance); - - Set> eventDescriptions = processInstance.getEventDescriptions(); + public void testSignalBoundaryEventInterrupting() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = SignalBoundaryEventInterruptingProcess.newProcess(app); + SignalBoundaryEventInterruptingModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + Set> eventDescriptions = instance.events(); assertThat(eventDescriptions).hasSize(2).extracting("event").contains("MyMessage", "workItemCompleted"); assertThat(eventDescriptions).extracting("eventType").contains("signal", "workItem"); - assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId()); + assertThat(eventDescriptions).extracting("processInstanceId").contains(instance.id()); assertThat(eventDescriptions).filteredOn("eventType", "signal").hasSize(1).extracting("properties", Map.class) .anyMatch(m -> m.containsKey("AttachedToID") && m.containsKey("AttachedToName")); - - kruntime.signalEvent("MyMessage", null); - assertProcessInstanceFinished(processInstance, kruntime); - + instance.send(Sig.of("MyMessage", null)); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testSignalIntermediateThrow() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventSignal.bpmn2"); - - Map params = new HashMap<>(); - params.put("x", "MyValue"); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateThrowEventSignal", params); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); - + public void testSignalIntermediateThrow() { + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process processDefinition = IntermediateThrowEventSignalProcess.newProcess(app); + IntermediateThrowEventSignalModel model = processDefinition.createModel(); + model.setX("MyValue"); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testSignalBetweenProcesses() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchSignalSingle.bpmn2", - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventSignal.bpmn2"); - + public void testSignalBetweenProcesses() { + Application app = ProcessTestHelper.newApplication(); TestWorkItemHandler handler = new TestWorkItemHandler(); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); + ProcessTestHelper.registerHandler(app, "Human Task", handler); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchSignalSingle"); - kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), null); + org.kie.kogito.process.Process catchSignalSingleProcess = IntermediateCatchSignalSingleProcess.newProcess(app); + org.kie.kogito.process.Process throwEventSignalProcess = IntermediateThrowEventSignalProcess.newProcess(app); - KogitoProcessInstance processInstance2 = kruntime.startProcess("IntermediateThrowEventSignal"); - assertProcessInstanceFinished(processInstance2, kruntime); + org.kie.kogito.process.ProcessInstance signalSingleProcessInstance = catchSignalSingleProcess.createInstance(catchSignalSingleProcess.createModel()); + signalSingleProcessInstance.start(); + assertThat(signalSingleProcessInstance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); - assertProcessInstanceFinished(processInstance, kruntime); + KogitoWorkItem workItem = handler.getWorkItem(); + assertThat(workItem).isNotNull(); + signalSingleProcessInstance.completeWorkItem(workItem.getStringId(), null, SecurityPolicy.of("user", Collections.emptyList())); + + org.kie.kogito.process.ProcessInstance throwEventSignalProcessInstance = throwEventSignalProcess.createInstance(throwEventSignalProcess.createModel()); + throwEventSignalProcessInstance.start(); + assertThat(throwEventSignalProcessInstance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); + assertThat(signalSingleProcessInstance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testEventBasedSplit() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventBasedSplit.bpmn2"); + public void testEventBasedSplit() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Email1", new SystemOutWorkItemHandler()); + ProcessTestHelper.registerHandler(app, "Email2", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - // Yes - KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit"); - assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = EventBasedSplitProcess.newProcess(app); + EventBasedSplitModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); - Set> eventDescriptions = processInstance.getEventDescriptions(); - assertThat(eventDescriptions).hasSize(2).extracting("event").contains("Yes", "No"); - assertThat(eventDescriptions).extracting("eventType").contains("signal"); - assertThat(eventDescriptions).extracting("dataType").hasOnlyElementsOfType(NamedDataType.class) + Set> eventDescriptions = instance.events(); + assertThat(eventDescriptions).hasSize(2).extracting(EventDescription::getEvent).contains("Yes", "No"); + assertThat(eventDescriptions).extracting(EventDescription::getEventType).contains("signal"); + assertThat(eventDescriptions).extracting(EventDescription::getDataType).hasOnlyElementsOfType(NamedDataType.class) .extracting("dataType").hasOnlyElementsOfType(StringDataType.class); - assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId()); - assertThat(eventDescriptions).extracting("nodeInstanceId").doesNotContainNull(); + assertThat(eventDescriptions).extracting(EventDescription::getProcessInstanceId).contains(instance.id()); + assertThat(eventDescriptions).extracting(EventDescription::getNodeInstanceId).doesNotContainNull(); - kruntime.signalEvent("Yes", "YesValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); - // No - processInstance = kruntime.startProcess("EventBasedSplit"); - assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - kruntime.signalEvent("No", "NoValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); + instance.send(Sig.of("Yes", "YesValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); + instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + + instance.send(Sig.of("No", "NoValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testEventBasedSplitBefore() throws Exception { - // signaling before the split is reached should have no effect - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventBasedSplit.bpmn2"); + public void testEventBasedSplitBefore() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Email1", new DoNothingWorkItemHandler()); + ProcessTestHelper.registerHandler(app, "Email2", new DoNothingWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new DoNothingWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); - // Yes - KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit"); - assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new DoNothingWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); - kruntime.signalEvent("Yes", "YesValue", processInstance.getStringId()); - assertProcessInstanceActive(processInstance); - // No - processInstance = kruntime.startProcess("EventBasedSplit"); - assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new DoNothingWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); - kruntime.signalEvent("No", "NoValue", processInstance.getStringId()); - assertProcessInstanceActive(processInstance); + org.kie.kogito.process.Process processDefinition = EventBasedSplitProcess.newProcess(app); + EventBasedSplitModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + + instance.send(Sig.of("Yes", "YesValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + + instance.send(Sig.of("No", "NoValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); } @Test - public void testEventBasedSplitAfter() throws Exception { - // signaling the other alternative after one has been selected should - // have no effect - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventBasedSplit.bpmn2"); + public void testEventBasedSplitAfter() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Email1", new SystemOutWorkItemHandler()); + ProcessTestHelper.registerHandler(app, "Email2", new DoNothingWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); - // Yes - KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit"); - assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); - kruntime.signalEvent("Yes", "YesValue", processInstance.getStringId()); - assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); - // No - kruntime.signalEvent("No", "NoValue", processInstance.getStringId()); + org.kie.kogito.process.Process processDefinition = EventBasedSplitProcess.newProcess(app); + EventBasedSplitModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.send(Sig.of("Yes", "YesValue")); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.send(Sig.of("No", "NoValue")); } @Test - public void testEventBasedSplit2() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener( - 2); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventBasedSplit2.bpmn2"); + public void testEventBasedSplit2() { + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(2); + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Email1", new SystemOutWorkItemHandler()); + ProcessTestHelper.registerHandler(app, "Email2", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - // Yes - KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit2"); - assertProcessInstanceActive(processInstance); + org.kie.kogito.process.Process processDefinition = EventBasedSplit2Process.newProcess(app); + EventBasedSplit2Model model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); - Set> eventDescriptions = processInstance.getEventDescriptions(); + Set> eventDescriptions = instance.events(); assertThat(eventDescriptions).hasSize(2).extracting("event").contains("Yes", TIMER_TRIGGERED_EVENT); assertThat(eventDescriptions).extracting("eventType").contains("signal", "timer"); assertThat(eventDescriptions).filteredOn(i -> i.getDataType() != null).extracting("dataType") .hasOnlyElementsOfType(NamedDataType.class).extracting("dataType") .hasOnlyElementsOfType(StringDataType.class); - assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId()); + assertThat(eventDescriptions).extracting("processInstanceId").contains(instance.id()); assertThat(eventDescriptions).filteredOn("eventType", "timer").hasSize(1).extracting("properties", Map.class) .anyMatch(m -> m.containsKey("TimerID") && m.containsKey("Delay")); - kruntime.signalEvent("Yes", "YesValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); - - // Timer - processInstance = kruntime.startProcess("EventBasedSplit2"); - assertProcessInstanceActive(processInstance); + instance.send(Sig.of("Yes", "YesValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); + instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); - - assertProcessInstanceFinished(processInstance, kruntime); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test @@ -499,34 +548,37 @@ public void testEventBasedSplit3() throws Exception { } @Test - public void testEventBasedSplit4() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventBasedSplit4.bpmn2"); + public void testEventBasedSplit4() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Email1", new SystemOutWorkItemHandler()); + ProcessTestHelper.registerHandler(app, "Email2", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - // Yes - KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit4"); - assertProcessInstanceActive(processInstance); + org.kie.kogito.process.Process processDefinition = EventBasedSplit4Process.newProcess(app); + EventBasedSplit4Model model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); - Set> eventDescriptions = processInstance.getEventDescriptions(); - assertThat(eventDescriptions).hasSize(2).extracting("event").contains("Message-YesMessage", - "Message-NoMessage"); - assertThat(eventDescriptions).extracting("eventType").contains("message", "message"); - assertThat(eventDescriptions).extracting("dataType").hasOnlyElementsOfType(NamedDataType.class) - .extracting("dataType").hasOnlyElementsOfType(StringDataType.class); - assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId()); + Set> eventDescriptions = instance.events(); + assertThat(eventDescriptions).hasSize(2) + .extracting(EventDescription::getEvent) + .contains("Message-YesMessage", "Message-NoMessage"); + assertThat(eventDescriptions).extracting(EventDescription::getEventType) + .contains("message", "message"); + assertThat(eventDescriptions).extracting(EventDescription::getDataType) + .hasOnlyElementsOfType(NamedDataType.class); + assertThat(eventDescriptions).extracting(event -> ((NamedDataType) event.getDataType()).getDataType()) + .hasOnlyElementsOfType(StringDataType.class); + assertThat(eventDescriptions).extracting(EventDescription::getProcessInstanceId) + .contains(instance.id()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - kruntime.signalEvent("Message-YesMessage", "YesValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - // No - processInstance = kruntime.startProcess("EventBasedSplit4"); - kruntime.signalEvent("Message-NoMessage", "NoValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); + instance.send(Sig.of("Message-YesMessage", "YesValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); + instance = processDefinition.createInstance(model); + instance.start(); + instance.send(Sig.of("Message-NoMessage", "NoValue")); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test @@ -929,6 +981,7 @@ public void testEventSubprocessMessageWithLocalVars() throws Exception { @Override public void afterNodeLeft(ProcessNodeLeftEvent event) { + @SuppressWarnings("unchecked") Map variable = (Map) event.getNodeInstance().getVariable("richiesta"); if (variable != null) { @@ -1040,7 +1093,6 @@ public void testTimerBoundaryEventDurationISO() throws Exception { countDownListener.waitTillCompleted(); assertProcessInstanceFinished(processInstance, kruntime); - } @Test @@ -1062,35 +1114,39 @@ public void testTimerBoundaryEventDateISO() throws Exception { } @Test - public void testTimerBoundaryEventCycle1() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); - - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventCycle1.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - KogitoProcessInstance processInstance = kruntime.startProcess("TimerBoundaryEventCycle1"); - assertProcessInstanceActive(processInstance); - countDownListener.waitTillCompleted(); + public void testTimerBoundaryEventCycle1() { + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(2); + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); - assertProcessInstanceFinished(processInstance, kruntime); + org.kie.kogito.process.Process processDefinition = TimerBoundaryEventCycle1Process.newProcess(app); + TimerBoundaryEventCycle1Model model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + countDownListener.waitTillCompleted(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testTimerBoundaryEventCycle2() throws Exception { - NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener( - "TimerEvent", 3); - - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventCycle2.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - KogitoProcessInstance processInstance = kruntime.startProcess("TimerBoundaryEventCycle2"); - assertProcessInstanceActive(processInstance); - countDownListener.waitTillCompleted(); + public void testTimerBoundaryEventCycle2() { + NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("TimerEvent", 3); + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); - assertProcessInstanceActive(processInstance); - kruntime.abortProcessInstance(processInstance.getStringId()); + org.kie.kogito.process.Process processDefinition = TimerBoundaryEventCycle2Process.newProcess(app); + TimerBoundaryEventCycle2Model model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + countDownListener.waitTillCompleted(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + instance.abort(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ABORTED); } @Test @@ -1109,62 +1165,59 @@ public void testTimerBoundaryEventCycleISO() throws Exception { } @Test - public void testTimerBoundaryEventInterrupting() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); + public void testTimerBoundaryEventInterrupting() { + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(2); + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventInterrupting.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - KogitoProcessInstance processInstance = kruntime.startProcess("TimerBoundaryEventInterrupting"); - assertProcessInstanceActive(processInstance); + org.kie.kogito.process.Process processDefinition = TimerBoundaryEventInterruptingProcess.newProcess(app); + TimerBoundaryEventInterruptingModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); - logger.debug("Firing timer"); - - assertProcessInstanceFinished(processInstance, kruntime); - + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test - public void testTimerBoundaryEventInterruptingOnTask() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); + public void testTimerBoundaryEventInterruptingOnTask() { + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(2); // Expecting 2 completion events + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new TestWorkItemHandler()); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventInterruptingOnTask.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new TestWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); + org.kie.kogito.process.Process processDefinition = TimerBoundaryEventInterruptingOnTaskProcess.newProcess(app); + TimerBoundaryEventInterruptingOnTaskModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); - KogitoProcessInstance processInstance = kruntime.startProcess("TimerBoundaryEventInterruptingOnTask"); - assertProcessInstanceActive(processInstance); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); - logger.debug("Firing timer"); - - assertProcessInstanceFinished(processInstance, kruntime); - + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testTimerBoundaryEventInterruptingOnTaskCancelTimer() throws Exception { - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventInterruptingOnTaskCancelTimer.bpmn2"); + public void testTimerBoundaryEventInterruptingOnTaskCancelTimer() { + Application app = ProcessTestHelper.newApplication(); TestWorkItemHandler handler = new TestWorkItemHandler(); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); - KogitoProcessInstance processInstance = kruntime - .startProcess("TimerBoundaryEventInterruptingOnTaskCancelTimer"); - assertProcessInstanceActive(processInstance); - - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); - kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), null); - - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); + ProcessTestHelper.registerHandler(app, "Human Task", handler); + org.kie.kogito.process.Process processDefinition = TimerBoundaryEventInterruptingOnTaskCancelTimerProcess.newProcess(app); + TimerBoundaryEventInterruptingOnTaskCancelTimerModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); KogitoWorkItem workItem = handler.getWorkItem(); - if (workItem != null) { - kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), null); - } - - assertProcessInstanceFinished(processInstance, kruntime); + assertThat(workItem).isNotNull(); + instance.completeWorkItem(workItem.getStringId(), null); + workItem = handler.getWorkItem(); + assertThat(workItem).isNotNull(); + instance.completeWorkItem(workItem.getStringId(), null); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test @@ -1182,136 +1235,142 @@ public void testIntermediateCatchEventSignal() throws Exception { } @Test - public void testIntermediateCatchEventMessage() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventMessage.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventMessage"); - assertProcessInstanceActive(processInstance); // now signal process instance - kruntime.signalEvent("Message-HelloMessage", "SomeValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); - + public void testIntermediateCatchEventMessage() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new SystemOutWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventMessageProcess.newProcess(app); + IntermediateCatchEventMessageModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.send(Sig.of("Message-HelloMessage", "SomeValue")); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventMessageWithRef() throws Exception { - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventMessageWithRef.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventMessageWithRef"); - assertProcessInstanceActive(processInstance); - - // now signal process instance - kruntime.signalEvent("Message-HelloMessage", "SomeValue", processInstance.getStringId()); - assertProcessInstanceFinished(processInstance, kruntime); - + public void testIntermediateCatchEventMessageWithRef() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new SystemOutWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventMessageWithRefProcess.newProcess(app); + IntermediateCatchEventMessageWithRefModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.send(Sig.of("Message-HelloMessage", "SomeValue")); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventTimerDuration() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); + public void testIntermediateCatchEventTimerDuration() { - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerDuration.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerDuration"); - assertProcessInstanceActive(processInstance); + Application app = ProcessTestHelper.newApplication(); - // now wait for 1 second for timer to trigger - countDownListener.waitTillCompleted(); + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(1); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); - assertProcessInstanceFinished(processInstance, kruntime); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerDurationProcess.newProcess(app); + IntermediateCatchEventTimerDurationModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + countDownListener.waitTillCompleted(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventTimerDateISO() throws Exception { + public void testIntermediateCatchEventTimerDateISO() { + Application app = ProcessTestHelper.newApplication(); ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerDateISO.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - - HashMap params = new HashMap<>(); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerDateISOProcess.newProcess(app); + IntermediateCatchEventTimerDateISOModel model = processDefinition.createModel(); OffsetDateTime plusTwoSeconds = OffsetDateTime.now().plusSeconds(2); - params.put("date", plusTwoSeconds.toString()); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerDateISO", params); - assertProcessInstanceActive(processInstance); - // now wait for 1 second for timer to trigger - countDownListener.waitTillCompleted(); + model.setDate(plusTwoSeconds.toString()); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - assertProcessInstanceFinished(processInstance, kruntime); + boolean completed = countDownListener.waitTillCompleted(3000); + assertThat(completed).isTrue(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventTimerDurationISO() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); - - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerDurationISO.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); + public void testIntermediateCatchEventTimerDurationISO() { + Application app = ProcessTestHelper.newApplication(); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerDurationISO"); - assertProcessInstanceActive(processInstance); - // now wait for 1.5 second for timer to trigger - countDownListener.waitTillCompleted(); + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); - assertProcessInstanceFinished(processInstance, kruntime); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerDurationISOProcess.newProcess(app); + IntermediateCatchEventTimerDurationISOModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + boolean completed = countDownListener.waitTillCompleted(2000); + assertThat(completed).isTrue(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventTimerCycle1() throws Exception { - ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); - - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerCycle1.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerCycle1"); - assertProcessInstanceActive(processInstance); - // now wait for 1 second for timer to trigger - countDownListener.waitTillCompleted(); + public void testIntermediateCatchEventTimerCycle1() { + Application app = ProcessTestHelper.newApplication(); + ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(); // Expecting 1 completion event + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); - assertProcessInstanceFinished(processInstance, kruntime); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerCycle1Process.newProcess(app); + IntermediateCatchEventTimerCycle1Model model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + boolean completed = countDownListener.waitTillCompleted(2000); // Wait for up to 2 seconds + assertThat(completed).isTrue(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventTimerCycleISO() throws Exception { + public void testIntermediateCatchEventTimerCycleISO() { + Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("timer", 5); - - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerCycleISO.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); - - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerCycleISO"); - assertProcessInstanceActive(processInstance); - - countDownListener.waitTillCompleted(); - assertProcessInstanceActive(processInstance); - kruntime.abortProcessInstance(processInstance.getStringId()); - + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerCycleISOProcess.newProcess(app); + IntermediateCatchEventTimerCycleISOModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + boolean completed = countDownListener.waitTillCompleted(); + assertThat(completed).isTrue(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.abort(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ABORTED); } @Test - public void testIntermediateCatchEventTimerCycle2() throws Exception { + public void testIntermediateCatchEventTimerCycle2() { + Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("timer", 3); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); - kruntime = createKogitoProcessRuntime( - "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerCycle2.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - kruntime.getProcessEventManager().addEventListener(countDownListener); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerCycle2Process.newProcess(app); + IntermediateCatchEventTimerCycle2Model model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerCycle2"); - assertProcessInstanceActive(processInstance); // now wait for 1 second for timer to trigger - countDownListener.waitTillCompleted(); - assertProcessInstanceActive(processInstance); - kruntime.abortProcessInstance(processInstance.getStringId()); - + boolean completed = countDownListener.waitTillCompleted(); // Wait for up to 10 seconds + assertThat(completed).isTrue(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.abort(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ABORTED); } @Test @@ -1434,27 +1493,34 @@ public void testIntermediateCatchEventTimerCycleWithErrorWithPersistence() throw } @Test - public void testNoneIntermediateThrow() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventNone.bpmn2"); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateThrowEventNone"); - assertProcessInstanceCompleted(processInstance); - + public void testNoneIntermediateThrow() { + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process processDefinition = IntermediateThrowEventNoneProcess.newProcess(app); + IntermediateThrowEventNoneModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testLinkIntermediateEvent() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateLinkEvent.bpmn2"); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateLinkEvent"); - assertProcessInstanceCompleted(processInstance); - + public void testLinkIntermediateEvent() { + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process processDefinition = IntermediateLinkEventProcess.newProcess(app); + IntermediateLinkEventModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testLinkEventCompositeProcess() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-LinkEventCompositeProcess.bpmn2"); - KogitoProcessInstance processInstance = kruntime.startProcess("LinkEventCompositeProcess"); - assertProcessInstanceCompleted(processInstance); + public void testLinkEventCompositeProcess() { + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process processDefinition = LinkEventCompositeProcessProcess.newProcess(app); + LinkEventCompositeProcessModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test From 892d197124bb4bb4021cfbeeb0002b1a6881d8a1 Mon Sep 17 00:00:00 2001 From: Abhiram Gundala <164050036+Abhitocode@users.noreply.github.com> Date: Mon, 16 Sep 2024 04:15:53 -0400 Subject: [PATCH 03/15] [incubator-kie-issues-1131] v7 migration to code generation (#3641) --- .../jbpm/bpmn2/StandaloneBPMNProcessTest.java | 281 +++++++++++------- 1 file changed, 167 insertions(+), 114 deletions(-) diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java index d38604d1a24..86bfb76e445 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java @@ -48,6 +48,8 @@ import org.jbpm.bpmn2.data.Evaluation3Process; import org.jbpm.bpmn2.data.EvaluationModel; import org.jbpm.bpmn2.data.EvaluationProcess; +import org.jbpm.bpmn2.error.ErrorBoundaryEventInterruptingModel; +import org.jbpm.bpmn2.error.ErrorBoundaryEventInterruptingProcess; import org.jbpm.bpmn2.event.ErrorEndEventModel; import org.jbpm.bpmn2.event.ErrorEndEventProcess; import org.jbpm.bpmn2.event.SignalEndEventModel; @@ -64,25 +66,50 @@ import org.jbpm.bpmn2.flow.MinimalWithDIGraphicalProcess; import org.jbpm.bpmn2.flow.MinimalWithGraphicalModel; import org.jbpm.bpmn2.flow.MinimalWithGraphicalProcess; +import org.jbpm.bpmn2.flow.MultiInstanceLoopCharacteristicsProcessModel; +import org.jbpm.bpmn2.flow.MultiInstanceLoopCharacteristicsProcessProcess; import org.jbpm.bpmn2.flow.SubProcessModel; import org.jbpm.bpmn2.flow.SubProcessProcess; import org.jbpm.bpmn2.flow.UserTaskModel; import org.jbpm.bpmn2.flow.UserTaskProcess; import org.jbpm.bpmn2.handler.ReceiveTaskHandler; import org.jbpm.bpmn2.handler.SendTaskHandler; +import org.jbpm.bpmn2.intermediate.EventBasedSplit2Model; +import org.jbpm.bpmn2.intermediate.EventBasedSplit2Process; import org.jbpm.bpmn2.intermediate.EventBasedSplit4Model; import org.jbpm.bpmn2.intermediate.EventBasedSplit4Process; import org.jbpm.bpmn2.intermediate.EventBasedSplitModel; import org.jbpm.bpmn2.intermediate.EventBasedSplitProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventMessageProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventSignalModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventSignalProcess; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationModel; +import org.jbpm.bpmn2.intermediate.IntermediateCatchEventTimerDurationProcess; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageModel; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageProcess; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventNoneModel; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventNoneProcess; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventSignalModel; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventSignalProcess; import org.jbpm.bpmn2.objects.Person; import org.jbpm.bpmn2.objects.TestWorkItemHandler; +import org.jbpm.bpmn2.start.MessageStartModel; +import org.jbpm.bpmn2.start.MessageStartProcess; +import org.jbpm.bpmn2.start.SignalStartModel; +import org.jbpm.bpmn2.start.SignalStartProcess; +import org.jbpm.bpmn2.start.TimerStartProcess; import org.jbpm.bpmn2.subprocess.CallActivityModel; import org.jbpm.bpmn2.subprocess.CallActivityProcess; import org.jbpm.bpmn2.subprocess.CallActivitySubProcessProcess; +import org.jbpm.bpmn2.task.ReceiveTaskModel; +import org.jbpm.bpmn2.task.ReceiveTaskProcess; import org.jbpm.bpmn2.task.SendTaskModel; import org.jbpm.bpmn2.task.SendTaskProcess; +import org.jbpm.bpmn2.timer.TimerBoundaryEventDurationModel; +import org.jbpm.bpmn2.timer.TimerBoundaryEventDurationProcess; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingModel; +import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingProcess; import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; @@ -101,7 +128,6 @@ import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.impl.Sig; import org.w3c.dom.Document; @@ -363,23 +389,24 @@ public void testEventBasedSplitAfter() { @Timeout(10) public void testEventBasedSplit2() throws Exception { ProcessCompletedCountDownProcessEventListener countDownListener = new ProcessCompletedCountDownProcessEventListener(2); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventBasedSplit2.bpmn2"); - - kruntime.getProcessEventManager().addEventListener(countDownListener); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - // Yes - KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit2"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - kruntime.signalEvent("Yes", "YesValue", processInstance.getStringId()); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); - - // Timer - processInstance = kruntime.startProcess("EventBasedSplit2"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerHandler(app, "Email1", new SystemOutWorkItemHandler()); + ProcessTestHelper.registerHandler(app, "Email2", new SystemOutWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = EventBasedSplit2Process.newProcess(app); + EventBasedSplit2Model modelYes = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instanceYes = processDefinition.createInstance(modelYes); + instanceYes.start(); + assertThat(instanceYes.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); + instanceYes.send(Sig.of("Yes", "YesValue")); + assertThat(instanceYes.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); + EventBasedSplit2Model modelTimer = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instanceTimer = processDefinition.createInstance(modelTimer); + instanceTimer.start(); + assertThat(instanceTimer.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + assertThat(instanceYes.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); + assertThat(instanceTimer.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test @@ -484,57 +511,67 @@ public void testSubProcess() { @Test public void testMultiInstanceLoopCharacteristicsProcess() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/flow/BPMN2-MultiInstanceLoopCharacteristicsProcess.bpmn2"); - Map params = new HashMap<>(); + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process definition = MultiInstanceLoopCharacteristicsProcessProcess.newProcess(app); + MultiInstanceLoopCharacteristicsProcessModel model = definition.createModel(); List myList = new ArrayList<>(); myList.add("First Item"); myList.add("Second Item"); - params.put("list", myList); - KogitoProcessInstance processInstance = kruntime.startProcess("MultiInstanceLoopCharacteristicsProcess", params); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); + model.setList(myList); + ProcessInstance processInstance = definition.createInstance(model); + processInstance.start(); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test public void testErrorBoundaryEvent() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/error/BPMN2-ErrorBoundaryEventInterrupting.bpmn2"); - - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("ErrorBoundaryEventInterrupting"); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + org.kie.kogito.process.Process definition = ErrorBoundaryEventInterruptingProcess.newProcess(app); + ErrorBoundaryEventInterruptingModel model = definition.createModel(); + ProcessInstance processInstance = definition.createInstance(model); + processInstance.start(); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test @Timeout(10) public void testTimerBoundaryEvent() throws Exception { + Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("TimerEvent", 1); ProcessCompletedCountDownProcessEventListener processEventListener = new ProcessCompletedCountDownProcessEventListener(); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventDuration.bpmn2"); - - kruntime.getProcessEventManager().addEventListener(countDownListener); - kruntime.getProcessEventManager().addEventListener(processEventListener); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("TimerBoundaryEventDuration"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerProcessEventListener(app, processEventListener); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + org.kie.kogito.process.Process definition = TimerBoundaryEventDurationProcess.newProcess(app); + TimerBoundaryEventDurationModel model = definition.createModel(); + org.kie.kogito.process.ProcessInstance processInstance = definition.createInstance(model); + processInstance.start(); + assertThat(processInstance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); processEventListener.waitTillCompleted(); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + assertThat(processInstance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test @Timeout(10) - public void testTimerBoundaryEventInterrupting() throws Exception { + public void testTimerBoundaryEventInterrupting() { + Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("TimerEvent", 1); ProcessCompletedCountDownProcessEventListener processEventListener = new ProcessCompletedCountDownProcessEventListener(); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/timer/BPMN2-TimerBoundaryEventInterrupting.bpmn2"); - - kruntime.getProcessEventManager().addEventListener(countDownListener); - kruntime.getProcessEventManager().addEventListener(processEventListener); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("TimerBoundaryEventInterrupting"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); + ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); + ProcessTestHelper.registerProcessEventListener(app, processEventListener); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + org.kie.kogito.process.Process processDefinition = TimerBoundaryEventInterruptingProcess.newProcess(app); + TimerBoundaryEventInterruptingModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + logger.debug("Starting process instance"); + instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); processEventListener.waitTillCompleted(); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test @@ -627,46 +664,50 @@ public void testAdHocSubProcessEmptyCompleteExpression() throws Exception { } @Test - public void testIntermediateCatchEventSignal() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventSignal.bpmn2"); - - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventSignal"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - // now signal process instance - kruntime.signalEvent("MyMessage", "SomeValue", processInstance.getStringId()); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + public void testIntermediateCatchEventSignal() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new SystemOutWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventSignalProcess.newProcess(app); + IntermediateCatchEventSignalModel model = processDefinition.createModel(); + ProcessInstance processInstance = processDefinition.createInstance(model); + processInstance.start(); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + processInstance.send(Sig.of("MyMessage", "SomeValue")); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testIntermediateCatchEventMessage() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventMessage.bpmn2"); - - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); - - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventMessage"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - // now signal process instance - kruntime.signalEvent("Message-HelloMessage", "SomeValue", processInstance.getStringId()); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + public void testIntermediateCatchEventMessage() { + Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new SystemOutWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventMessageProcess.newProcess(app); + IntermediateCatchEventMessageModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + instance.send(Sig.of("Message-HelloMessage", "SomeValue")); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test @Timeout(10) - public void testIntermediateCatchEventTimer() throws Exception { + public void testIntermediateCatchEventTimer() { + Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("timer", 1); ProcessCompletedCountDownProcessEventListener processEventListener = new ProcessCompletedCountDownProcessEventListener(); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateCatchEventTimerDuration.bpmn2"); - - kruntime.getProcessEventManager().addEventListener(countDownListener); - kruntime.getProcessEventManager().addEventListener(processEventListener); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateCatchEventTimerDuration"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - // now wait for 1 second for timer to trigger - countDownListener.waitTillCompleted(); - processEventListener.waitTillCompleted(); - assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + ProcessTestHelper.registerProcessEventListener(app, processEventListener); + ProcessTestHelper.registerHandler(app, "Human Task", new DoNothingWorkItemHandler()); + org.kie.kogito.process.Process processDefinition = IntermediateCatchEventTimerDurationProcess.newProcess(app); + IntermediateCatchEventTimerDurationModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + boolean timerCompleted = countDownListener.waitTillCompleted(); + boolean processCompleted = processEventListener.waitTillCompleted(); + assertThat(timerCompleted).isTrue(); + assertThat(processCompleted).isTrue(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test @@ -710,14 +751,19 @@ public void testSendTask() { @Test public void testReceiveTask() throws Exception { + Application app = ProcessTestHelper.newApplication(); kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/task/BPMN2-ReceiveTask.bpmn2"); - ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(kruntime); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); - KogitoWorkflowProcessInstance processInstance = (KogitoWorkflowProcessInstance) kruntime.startProcess("ReceiveTask"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); + ProcessTestHelper.registerHandler(app, "Receive Task", receiveTaskHandler); + org.kie.kogito.process.Process processDefinition = ReceiveTaskProcess.newProcess(app); + ReceiveTaskModel model = processDefinition.createModel(); + org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); + instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + receiveTaskHandler.setKnowledgeRuntime(kruntime); receiveTaskHandler.messageReceived("HelloMessage", "Hello john!"); - assertProcessInstanceCompleted(((KogitoProcessInstance) processInstance).getStringId(), kruntime); + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "john"); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @Test @@ -738,34 +784,35 @@ public void testConditionalStart() throws Exception { @Test @Timeout(1000) public void testTimerStart() throws Exception { + Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("StartProcess", 5); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/start/BPMN2-TimerStart.bpmn2"); - - kruntime.getProcessEventManager().addEventListener(countDownListener); - final List list = new ArrayList<>(); - kruntime.getProcessEventManager().addEventListener(new DefaultKogitoProcessEventListener() { - + ProcessTestHelper.registerProcessEventListener(app, countDownListener); + final List startedInstances = new ArrayList<>(); + ProcessTestHelper.registerProcessEventListener(app, new DefaultKogitoProcessEventListener() { + @Override public void beforeProcessStarted(ProcessStartedEvent event) { - list.add(((KogitoProcessInstance) event.getProcessInstance()).getStringId()); + startedInstances.add(((KogitoProcessInstance) event.getProcessInstance()).getStringId()); } - }); - - assertThat(list).isEmpty(); + TimerStartProcess.newProcess(app); + assertThat(startedInstances).isEmpty(); countDownListener.waitTillCompleted(); - assertThat(list).hasSize(5); + assertThat(startedInstances).hasSize(5); } @Test - public void testSignalStart() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/start/BPMN2-SignalStart.bpmn2"); + public void testSignalStart() { + Application app = ProcessTestHelper.newApplication(); final List list = new ArrayList<>(); - kruntime.getProcessEventManager().addEventListener(new DefaultKogitoProcessEventListener() { + ProcessTestHelper.registerProcessEventListener(app, new DefaultKogitoProcessEventListener() { + @Override public void afterProcessStarted(ProcessStartedEvent event) { - list.add(((KogitoProcessInstance) event.getProcessInstance()).getStringId()); + String processInstanceId = event.getProcessInstance().getId(); + list.add(processInstanceId); } }); - kruntime.signalEvent("MySignal", "NewValue"); + org.kie.kogito.process.Process process = SignalStartProcess.newProcess(app); + process.send(Sig.of("MySignal", "NewValue")); assertThat(list).hasSize(1); } @@ -783,16 +830,18 @@ public void testSignalEnd() { } @Test - public void testMessageStart() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/start/BPMN2-MessageStart.bpmn2"); - final List list = new ArrayList<>(); - kruntime.getProcessEventManager().addEventListener(new DefaultKogitoProcessEventListener() { - public void afterProcessStarted(ProcessStartedEvent event) { - list.add(((KogitoProcessInstance) event.getProcessInstance()).getStringId()); + public void testMessageStart() { + Application app = ProcessTestHelper.newApplication(); + final List startedProcesses = new ArrayList<>(); + ProcessTestHelper.registerProcessEventListener(app, new DefaultKogitoProcessEventListener() { + @Override + public void beforeProcessStarted(ProcessStartedEvent event) { + startedProcesses.add(((KogitoProcessInstance) event.getProcessInstance()).getStringId()); } }); - kruntime.signalEvent("Message-HelloMessage", "NewValue"); - assertThat(list).hasSize(1); + org.kie.kogito.process.Process definition = MessageStartProcess.newProcess(app); + definition.send(Sig.of("HelloMessage", "NewValue")); + assertThat(startedProcesses).hasSize(1); } @Test @@ -817,19 +866,23 @@ public void produce(KogitoProcessInstance pi, String eventData) { } @Test - public void testSignalIntermediateThrow() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventSignal.bpmn2"); - Map params = new HashMap<>(); - params.put("x", "MyValue"); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateThrowEventSignal", params); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); + public void testSignalIntermediateThrow() { + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process process = IntermediateThrowEventSignalProcess.newProcess(app); + IntermediateThrowEventSignalModel model = process.createModel(); + model.setX("MyValue"); + ProcessInstance processInstance = process.createInstance(model); + processInstance.start(); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test - public void testNoneIntermediateThrow() throws Exception { - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventNone.bpmn2"); - KogitoProcessInstance processInstance = kruntime.startProcess("IntermediateThrowEventNone"); - assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); + public void testNoneIntermediateThrow() { + Application app = ProcessTestHelper.newApplication(); + org.kie.kogito.process.Process process = IntermediateThrowEventNoneProcess.newProcess(app); + ProcessInstance processInstance = process.createInstance(process.createModel()); + processInstance.start(); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test From bbbffe6c902d1fbd0a34b9ffa8546ba9b5dc1d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Mu=C3=B1oz?= Date: Wed, 18 Sep 2024 07:44:34 +0200 Subject: [PATCH 04/15] Bump version.io.quarkiverse.embedded.postgresql to 0.2.3 (#3666) --- kogito-build/kogito-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kogito-build/kogito-dependencies-bom/pom.xml b/kogito-build/kogito-dependencies-bom/pom.xml index 2d60bd58d3a..760f481e8bb 100644 --- a/kogito-build/kogito-dependencies-bom/pom.xml +++ b/kogito-build/kogito-dependencies-bom/pom.xml @@ -53,7 +53,7 @@ 2.4.1 0.3.0 2.2.0 - 0.2.2 + 0.2.3 1.5.2 3.25.8 2.17.2 From 43f99d915d9ef06cdc1b7b23199828b7bfcd4c0d Mon Sep 17 00:00:00 2001 From: Enrique Date: Wed, 18 Sep 2024 08:46:54 +0200 Subject: [PATCH 05/15] [incubator-kie-issues-1439] UserTask Decouple codegen and interface from engine (#3655) --- .../common/human-task-prediction/api/pom.xml | 4 + .../PredictionAwareHumanTaskLifeCycle.java | 84 - ...edictionAwareHumanTaskWorkItemHandler.java | 65 + ...PredictionAwareHumanTaskLifeCycleTest.java | 7 +- .../predictions/smile/SmileRandomForest.java | 2 +- .../SmileRandomForestPredictionTest.java | 6 +- .../FileSystemProcessInstancesTest.java | 11 +- .../infinispan/CacheProcessInstancesIT.java | 19 +- .../CacheProcessInstancesWithLockIT.java | 9 +- .../jdbc/AbstractProcessInstancesIT.java | 10 +- .../mongodb/MongoDBProcessInstancesIT.java | 19 +- .../mongodb/PersistentProcessInstancesIT.java | 11 +- .../PersistentProcessInstancesWithLockIT.java | 7 +- .../PostgresqlProcessInstancesIT.java | 7 +- .../rocksdb/RockDBProcessInstancesTest.java | 7 +- ...BaseProcessInstanceManagementResource.java | 5 +- ...ProcessInstanceManagementResourceTest.java | 3 +- .../exceptions/BaseExceptionsHandler.java | 10 +- .../exceptions/BaseExceptionHandlerTest.java | 10 +- .../service/TaskManagementOperations.java | 6 +- .../service/TaskManagementService.java | 78 +- .../org/kie/kogito/auth/SecurityPolicy.java | 53 +- .../event/KogitoProcessEventListener.java | 52 - .../event/KogitoProcessEventSupport.java | 100 +- .../event/ProcessWorkItemTransitionEvent.java | 10 +- .../process/runtime/KogitoProcessRuntime.java | 1 + .../runtime/KogitoWorkItemNodeInstance.java | 2 + .../InvalidLifeCyclePhaseException.java | 2 +- .../workitem/InvalidTransitionException.java | 2 +- .../{runtime => workitem}/KogitoWorkItem.java | 27 +- .../KogitoWorkItemHandler.java | 49 +- .../KogitoWorkItemHandlerFactory.java | 39 + ...ogitoWorkItemHandlerNotFoundException.java | 2 +- .../KogitoWorkItemManager.java | 51 +- .../workitem/NotAuthorizedException.java | 2 +- .../process/workitem/Policy.java | 10 +- .../workitem/WorkItemExecutionException.java | 2 +- .../WorkItemHandlerRuntimeException.java | 2 +- .../process/workitem/WorkItemLifeCycle.java} | 41 +- .../workitem/WorkItemLifeCyclePhase.java} | 35 +- .../WorkItemNotFoundException.java | 2 +- .../process/workitem/WorkItemPhaseState.java | 53 + .../workitem/WorkItemTerminationType.java | 24 + .../process/workitem/WorkItemTransition.java} | 16 +- .../event/KogitoUserTaskEventSupport.java | 95 + .../java/org/kie/kogito/process/Process.java | 8 + .../kie/kogito/process/ProcessInstance.java | 20 +- .../kie/kogito/process/ProcessService.java | 40 +- .../java/org/kie/kogito/process/WorkItem.java | 4 + .../kogito/process/WorkItemHandlerConfig.java | 2 +- .../UnitOfWorkProcessEventListener.java | 68 - .../UnitOfWorkUserTaskEventListener.java | 88 + .../UserTask.java} | 48 +- .../kie/kogito/usertask/UserTaskConfig.java} | 29 +- .../usertask/UserTaskEventListener.java | 73 + .../usertask/UserTaskEventListenerConfig.java | 27 + .../kie/kogito/usertask/UserTaskInstance.java | 116 + .../kogito/usertask/UserTaskInstances.java | 40 + .../org/kie/kogito/usertask/UserTasks.java | 31 + .../events/UserTaskAssignmentEvent.java | 30 + .../events/UserTaskAttachmentEvent.java | 30 + .../usertask/events/UserTaskCommentEvent.java | 30 + .../events/UserTaskDeadlineEvent.java | 35 +- .../kogito/usertask/events/UserTaskEvent.java | 53 + .../usertask/events/UserTaskStateEvent.java | 28 + .../events/UserTaskVariableEvent.java | 35 + .../usertask/lifecycle/UserTaskLifeCycle.java | 37 + .../usertask/lifecycle/UserTaskState.java | 102 + .../lifecycle/UserTaskTransition.java | 31 + .../lifecycle/UserTaskTransitionExecutor.java | 29 + .../lifecycle/UserTaskTransitionToken.java | 28 + .../model}/Attachment.java | 4 +- .../model}/AttachmentInfo.java | 2 +- .../workitem => usertask/model}/Comment.java | 6 +- .../kogito/usertask/model}/DeadlineInfo.java | 2 +- .../kogito/usertask/model}/Reassignment.java | 2 +- .../kogito/usertask/model}/ScheduleInfo.java | 2 +- .../cloudevents/extension/ProcessMeta.java | 2 +- .../kogito/event/impl/BaseEventManager.java | 2 +- .../event/impl/DefaultInstanceEventBatch.java | 80 + .../event/impl/ProcessInstanceEventBatch.java | 543 -- .../adapter/AbstractDataEventAdapter.java | 130 + .../event/impl/adapter/AdapterHelper.java | 75 + .../event/impl/adapter/DataEventAdapter.java | 39 + ...ProcessCompletedEventDataEventAdapter.java | 36 + .../ProcessErrorEventDataEventAdapter.java | 58 + .../ProcessMigratedEventDataEventAdapter.java | 36 + ...ocessNodeEnteredEventDataEventAdapter.java | 57 + .../ProcessNodeLeftEventDataEventAdapter.java | 36 + .../ProcessSLAEventDataEventAdapter.java | 69 + .../ProcessStartedEventDataEventAdapter.java | 20 +- .../ProcessVariableEventDataEventAdapter.java | 76 + ...erTaskAssignmentEventDataEventAdapter.java | 57 + .../UserTaskCommentEventDataEventAdapter.java | 78 + ...UserTaskDeadlineEventDataEventAdapter.java | 56 + .../UserTaskStateEventDataEventAdapter.java | 76 + ...UserTaskVariableEventDataEventAdapter.java | 59 + ...erTastAttachmentEventDataEventAdapter.java | 79 + ...kogito.event.impl.adapter.DataEventAdapter | 14 + .../impl/ProcessInstanceEventBatchTest.java | 20 +- .../bpmn2/handler/ReceiveTaskHandler.java | 63 - .../java/org/jbpm/bpmn2/xml/TaskHandler.java | 1 + .../org/jbpm/bpmn2/xml/UserTaskHandler.java | 15 +- .../bpmn2/xpath/XPATHAssignmentBuilder.java | 1 + .../kie/kogito/process/bpmn2/BpmnProcess.java | 8 +- .../jbpm-deps-group-bpmn2-compiler/pom.xml | 4 + .../jbpm-deps-group-compiler/pom.xml | 4 + .../jbpm-deps-group-engine/pom.xml | 5 + .../AbstractServiceTaskDescriptor.java | 157 +- .../descriptors/ServiceTaskDescriptor.java | 2 +- ...NodeLeftCountDownProcessEventListener.java | 11 +- ...ompletedCountDownProcessEventListener.java | 5 + .../handler/TestWorkItemHandler.java | 20 +- .../main/java/org/jbpm/process/core/Work.java | 31 +- .../exception/ErrorCodeExceptionPolicy.java | 2 +- .../context/exception/ExceptionScope.java | 2 +- .../core/event/ExpressionEventTypeFilter.java | 2 +- .../org/jbpm/process/core/impl/WorkImpl.java | 73 +- ...AbstractProcessRuntimeServiceProvider.java | 2 +- .../instance/DummyKnowledgeRuntime.java | 2 +- .../instance/KogitoProcessRuntimeImpl.java | 2 +- .../process/instance/LightProcessRuntime.java | 2 +- .../instance/LightWorkItemManager.java | 368 +- .../ProcessRuntimeServiceProvider.java | 2 +- .../exception/CompensationScopeInstance.java | 14 +- .../DefaultExceptionScopeInstance.java | 6 +- .../event/KogitoProcessEventSupportImpl.java | 169 +- ...itoProcessWorkItemTransitionEventImpl.java | 12 +- .../event/UserTaskAttachmentEventImpl.java | 92 - .../event/UserTaskCommentEventImpl.java | 92 - .../instance/event/UserTaskEventImpl.java | 96 - .../actions/SignalProcessInstanceAction.java | 6 + .../instance/impl/demo/UIWorkItemHandler.java | 184 - .../impl/demo/UIWorkItemHandlerDialog.java | 176 - .../humantask/BaseHumanTaskLifeCycle.java | 145 - .../impl/humantask/HumanTaskHelper.java | 184 - .../impl/humantask/HumanTaskTransition.java | 81 - .../HumanTaskWorkItemDecoratorImpl.java | 466 -- .../humantask/HumanTaskWorkItemHandler.java | 74 - .../impl/humantask/HumanTaskWorkItemImpl.java | 230 - .../humantask/InternalHumanTaskWorkItem.java | 59 - .../instance/impl/humantask/phases/Claim.java | 83 - .../impl/humantask/phases/Release.java | 69 - .../instance/impl/humantask/phases/Skip.java | 85 - .../process/instance/impl/workitem/Abort.java | 67 - .../instance/impl/workitem/Complete.java | 88 - .../java/org/jbpm/util/ContextFactory.java | 2 +- .../java/org/jbpm/util/JsonSchemaUtil.java | 22 +- .../workflow/core/impl/DataAssociation.java | 7 +- .../core/impl}/XPATHAssignmentAction.java | 99 +- .../impl/WorkflowProcessInstanceImpl.java | 16 +- .../node/BoundaryEventNodeInstance.java | 4 + .../workflow/instance/node/DynamicUtils.java | 4 +- .../instance/node/HumanTaskNodeInstance.java | 230 +- .../instance/node/TimerNodeInstance.java | 2 +- .../instance/node/WorkItemNodeInstance.java | 30 +- .../kogito/process/impl/AbstractProcess.java | 50 +- .../process/impl/AbstractProcessInstance.java | 99 +- .../kie/kogito/process/impl/BaseWorkItem.java | 20 +- .../impl/CachedWorkItemHandlerConfig.java | 2 +- .../impl/DefaultWorkItemHandlerConfig.java | 8 +- .../impl/MultiWorkItemHandlerConfig.java | 2 +- .../process/impl/ProcessServiceImpl.java | 358 +- .../test/java/org/jbpm/process/TimerTest.java | 6 + .../java/org/jbpm/process/WorkItemTest.java | 6 +- .../exception/ExceptionHandlerPolicyTest.java | 2 +- .../process/test/TestWorkItemHandler.java | 17 +- .../org/jbpm/util/JsonSchemaUtilTest.java | 10 +- .../impl/AbstractProcessConfigTest.java | 2 +- jbpm/jbpm-tests/pom.xml | 6 +- .../objects/ExceptionOnPurposeHandler.java | 17 +- .../objects/TestUserTaskWorkItemHandler.java | 106 + .../bpmn2/objects/TestWorkItemHandler.java | 59 +- .../services/AlwaysThrowingComponent.java | 2 +- ...N2-DataInputAssociationsLazyCreating.bpmn2 | 8 +- ...PMN2-DataInputAssociationsXmlLiteral.bpmn2 | 2 +- .../BPMN2-DataOutputAssociationsXmlNode.bpmn2 | 4 +- .../java/org/jbpm/bpmn2/ActivityTest.java | 86 +- .../org/jbpm/bpmn2/CollaborationTest.java | 2 +- .../java/org/jbpm/bpmn2/CompensationTest.java | 4 +- .../test/java/org/jbpm/bpmn2/DataTest.java | 173 +- .../java/org/jbpm/bpmn2/EndEventTest.java | 2 +- .../java/org/jbpm/bpmn2/ErrorEventTest.java | 68 +- .../org/jbpm/bpmn2/EscalationEventTest.java | 18 +- .../test/java/org/jbpm/bpmn2/FlowTest.java | 39 +- .../org/jbpm/bpmn2/IntermediateEventTest.java | 88 +- .../org/jbpm/bpmn2/SLAComplianceTest.java | 4 +- .../jbpm/bpmn2/StandaloneBPMNProcessTest.java | 56 +- .../java/org/jbpm/bpmn2/StartEventTest.java | 4 +- .../java/org/jbpm/bpmn2/VariableTagsTest.java | 7 +- .../MultipleProcessesPerThreadTest.java | 2 +- .../concurrency/OneProcessPerThreadTest.java | 18 +- .../handler/ErrornousWorkItemHandler.java | 24 +- .../LoggingTaskHandlerWrapperTest.java | 3 +- .../WorkItemHandlerExceptionHandlingTest.java | 2 +- .../bpmn2/structureref/StructureRefTest.java | 28 +- .../jbpm/test/utils/ProcessTestHelper.java | 23 +- .../test/utils/ReceiveTaskTestHandler.java | 29 +- .../jbpm/test/utils/SendTaskTestHandler.java | 23 +- .../jbpm-tools-maven-plugin/pom.xml | 5 - jbpm/jbpm-usertask/pom.xml | 69 + .../jbpm/usertask/handler}/Policies.java | 8 +- .../UserTaskKogitoWorkItemHandler.java | 257 + .../UserTaskKogitoWorkItemHandlerFactory.java | 33 + .../kogito/usertask/impl/DefaultUserTask.java | 303 + .../usertask/impl/DefaultUserTaskConfig.java | 112 + .../DefaultUserTaskEventListenerConfig.java | 48 + .../impl/DefaultUserTaskInstance.java | 481 ++ .../usertask/impl/DefaultUserTasks.java | 64 + .../impl/InMemoryUserTaskInstances.java | 101 + .../impl/KogitoUserTaskEventSupportImpl.java | 194 + .../events}/UserTaskAssignmentEventImpl.java | 40 +- .../events/UserTaskAttachmentEventImpl.java | 59 + .../impl/events/UserTaskCommentEventImpl.java | 59 + .../events}/UserTaskDeadlineEventImpl.java | 21 +- .../impl/events/UserTaskEventImpl.java | 74 + .../impl/events}/UserTaskStateEventImpl.java | 23 +- .../events}/UserTaskVariableEventImpl.java | 16 +- .../lifecycle/DefaultUserTaskLifeCycle.java | 110 + .../DefaultUserTaskTransitionToken.java | 46 + .../lifecycle/DefaultUserTransition.java} | 48 +- .../usertask/impl/model}/DeadlineHelper.java | 5 +- ...cess.workitem.KogitoWorkItemHandlerFactory | 1 + .../impl/model}/DeadlineHelperTest.java | 7 +- jbpm/pom.xml | 1 + .../state/WorkItemNodeInstanceReader.java | 120 +- .../state/WorkItemNodeInstanceWriter.java | 129 +- .../KogitoNodeInstanceContentsProtobuf.java | 571 +- .../protobuf/KogitoWorkItemsProtobuf.java | 6744 +---------------- .../kogito_node_instance_contents.proto | 2 + .../protobuf/kogito_work_items.proto | 31 - jbpm/process-workitems/pom.xml | 2 +- .../AbstractExceptionHandlingTaskHandler.java | 36 +- .../DefaultKogitoWorkItemHandlerFactory.java | 33 + .../builtin/DoNothingWorkItemHandler.java | 28 + .../builtin}/LoggingTaskHandlerDecorator.java | 21 +- .../builtin}/MockDataWorkItemHandler.java | 21 +- .../workitem/builtin/ReceiveTaskHandler.java | 62 + .../workitem/builtin}/SendTaskHandler.java | 23 +- .../workitem/builtin}/ServiceTaskHandler.java | 25 +- .../SignallingTaskHandlerDecorator.java | 53 +- .../builtin/SystemOutWorkItemHandler.java | 46 + .../workitems/InternalKogitoWorkItem.java | 8 +- .../InternalKogitoWorkItemManager.java | 4 +- .../impl/DefaultKogitoWorkItemHandler.java | 135 + .../impl/DefaultWorkItemLifeCycle.java | 73 + .../impl/DefaultWorkItemLifeCyclePhase.java | 78 + .../impl/DefaultWorkItemTransitionImpl.java | 76 + .../impl/KogitoDefaultWorkItemManager.java | 271 +- .../workitems/impl/KogitoWorkItemImpl.java | 32 +- .../workitems/impl/WorkItemParamResolver.java | 2 +- ...cess.workitem.KogitoWorkItemHandlerFactory | 1 + .../impl/KogitoWorkItemImplTest.java | 2 +- kogito-bom/pom.xml | 5 + .../api/template/TemplatedGenerator.java | 7 +- .../utils/ApplicationGeneratorDiscovery.java | 7 +- .../kie/kogito/codegen/AbstractCodegenIT.java | 22 +- .../codegen/tests/CallActivityTaskIT.java | 27 +- .../kogito/codegen/tests/PublishEventIT.java | 35 +- .../kogito/codegen/tests/SignalEventIT.java | 4 + .../kie/kogito/codegen/tests/UserTaskIT.java | 322 +- .../kogito-codegen-processes/pom.xml | 5 - .../codegen/usertask/UserTaskCodegen.java | 263 + .../usertask/UserTaskCodegenFactory.java | 35 + .../usertask/UserTaskCodegenHelper.java | 53 + .../usertask/UserTaskConfigGenerator.java | 68 + .../usertask/UserTaskContainerGenerator.java | 79 + ...rg.kie.kogito.codegen.api.GeneratorFactory | 3 +- .../RestResourceQuarkusTemplate.java | 10 +- .../RestResourceSpringTemplate.java | 10 +- .../RestResourceUserTaskQuarkusTemplate.java | 144 +- .../RestResourceUserTaskSpringTemplate.java | 196 +- .../TaskModelFactoryTemplate.java | 3 + .../usertask/UserTaskConfigJavaTemplate.java | 28 + .../UserTaskConfigQuarkusTemplate.java | 52 + .../UserTaskConfigSpringTemplate.java | 52 + .../usertask/UserTaskJavaTemplate.java | 32 + .../usertask/UserTaskQuarkusTemplate.java | 40 + .../usertask/UserTaskSpringTemplate.java | 40 + .../UserTasksContainerJavaTemplate.java | 29 + .../UserTasksContainerQuarkusTemplate.java | 50 + .../UserTasksContainerSpringTemplate.java | 50 + kogito-maven-plugin/pom.xml | 3 + .../kogito/maven/plugin/AbstractKieMojo.java | 3 +- .../maven/plugin/GenerateModelMojo.java | 4 +- .../kogito/maven/plugin/util/MojoUtil.java | 9 +- .../StaticFunctionWorkItemHandler.java | 2 +- .../executor/StaticWorkflowApplication.java | 2 +- .../executor/StaticWorkflowProcess.java | 2 +- .../workflow/rpc/RPCWorkItemHandler.java | 2 +- .../python/PythonScriptWorkItemHandler.java | 2 +- .../workflow/ServiceWorkItemHandler.java | 2 +- .../workflow/WorkflowWorkItemHandler.java | 23 +- .../ConfigSuppliedWorkItemResolver.java | 2 +- .../ConfigWorkItemResolver.java | 2 +- .../ExpressionParametersFactory.java | 2 +- .../ExpressionWorkItemResolver.java | 2 +- .../workitemparams/JsonNodeResolver.java | 2 +- .../workitemparams/ObjectResolver.java | 2 +- .../workflow/JsonNodeJqResolverTest.java | 2 +- .../JsonNodeJsonPathResolverTest.java | 2 +- .../workitem/rest/RestWorkItemHandler.java | 22 +- .../rest/auth/ApiKeyAuthDecorator.java | 2 +- .../rest/auth/BasicAuthDecorator.java | 2 +- .../rest/auth/BearerTokenAuthDecorator.java | 2 +- .../rest/auth/OAuth2AuthDecorator.java | 2 +- .../decorators/AbstractParamsDecorator.java | 2 +- .../decorators/HeaderMetadataDecorator.java | 2 +- .../rest/decorators/RequestDecorator.java | 2 +- .../rest/RestWorkItemHandlerTest.java | 38 +- .../rest/decorators/ParamsDecoratorTest.java | 2 +- .../runtime/CamelCustomWorkItemHandler.java | 2 +- .../CloudEventKnativeParamsDecorator.java | 2 +- .../KnativeWorkItemHandler.java | 14 +- .../PlainJsonKnativeParamsDecorator.java | 2 +- .../kafka/KafkaProcessInstancesIT.java | 15 +- .../python/PythonWorkItemHandlerConfig.java | 2 +- .../InvalidLifeCyclePhaseExceptionMapper.java | 2 +- .../InvalidTransitionExceptionMapper.java | 2 +- .../NotAuthorizedExceptionMapper.java | 2 +- .../WorkItemExecutionExceptionMapper.java | 2 +- .../WorkItemNotFoundExceptionMapper.java | 2 +- .../management/TaskManagementResource.java | 8 +- .../org/acme/StatefulProcessResourceTest.java | 12 +- .../kogito-quarkus-processes/pom.xml | 3 +- .../quarkus/support/HumanTaskServiceImpl.java | 54 +- .../services/RPCCustomWorkItemHandler.java | 2 +- .../quarkus/workflows/CompensationRestIT.java | 11 +- .../openapi/OpenApiWorkItemHandler.java | 4 +- .../kie/kogito/wih/CustomWorkItemHandler.java | 22 +- .../org/acme/CustomTaskWorkItemHandler.java | 18 +- .../quarkus/ManagementAddOnIT.java | 4 +- .../integrationtests/quarkus/TaskIT.java | 92 +- .../springboot/ExceptionsHandler.java | 10 +- .../springboot/ExceptionsHandlerTest.java | 6 +- .../TaskManagementRestController.java | 2 +- springboot/archetype/pom.xml | 5 - .../pom.xml | 1 + .../.gitignore | 1 + .../pom.xml | 8 + .../.gitignore | 1 + .../springboot/ManagementAddOnTest.java | 4 +- .../integrationtests/springboot/TaskTest.java | 67 +- .../.gitignore | 1 + .../.gitignore | 1 + .../pom.xml | 6 +- .../.gitignore | 1 + .../kie/kogito/wih/CustomWorkItemHandler.java | 22 +- 348 files changed, 9053 insertions(+), 12988 deletions(-) delete mode 100644 addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycle.java create mode 100644 addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskWorkItemHandler.java rename api/kogito-api/src/main/java/org/kie/kogito/{ => internal}/process/workitem/InvalidLifeCyclePhaseException.java (95%) rename api/kogito-api/src/main/java/org/kie/kogito/{ => internal}/process/workitem/InvalidTransitionException.java (95%) rename api/kogito-api/src/main/java/org/kie/kogito/internal/process/{runtime => workitem}/KogitoWorkItem.java (80%) rename api/kogito-api/src/main/java/org/kie/kogito/internal/process/{runtime => workitem}/KogitoWorkItemHandler.java (55%) create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerFactory.java rename {jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems => api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem}/KogitoWorkItemHandlerNotFoundException.java (95%) rename api/kogito-api/src/main/java/org/kie/kogito/internal/process/{runtime => workitem}/KogitoWorkItemManager.java (74%) rename api/kogito-api/src/main/java/org/kie/kogito/{ => internal}/process/workitem/NotAuthorizedException.java (95%) rename api/kogito-api/src/main/java/org/kie/kogito/{ => internal}/process/workitem/Policy.java (85%) rename api/kogito-api/src/main/java/org/kie/kogito/{ => internal}/process/workitem/WorkItemExecutionException.java (97%) rename {jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler => api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem}/WorkItemHandlerRuntimeException.java (97%) rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem/LifeCycle.java => internal/process/workitem/WorkItemLifeCycle.java} (62%) rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem/LifeCyclePhase.java => internal/process/workitem/WorkItemLifeCyclePhase.java} (53%) rename api/kogito-api/src/main/java/org/kie/kogito/internal/process/{runtime => workitem}/WorkItemNotFoundException.java (96%) create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemPhaseState.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTerminationType.java rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem/Transition.java => internal/process/workitem/WorkItemTransition.java} (81%) create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/internal/usertask/event/KogitoUserTaskEventSupport.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkUserTaskEventListener.java rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem/HumanTaskWorkItem.java => usertask/UserTask.java} (73%) rename api/kogito-api/src/{test/java/org/kie/kogito/process/workitem/PoliciesTest.java => main/java/org/kie/kogito/usertask/UserTaskConfig.java} (60%) create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListener.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListenerConfig.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstances.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTasks.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAssignmentEvent.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAttachmentEvent.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskCommentEvent.java rename jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/SystemOutWorkItemHandler.java => api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskDeadlineEvent.java (52%) mode change 100755 => 100644 create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskEvent.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskStateEvent.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskVariableEvent.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskState.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransition.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionExecutor.java create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionToken.java rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem => usertask/model}/Attachment.java (93%) rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem => usertask/model}/AttachmentInfo.java (96%) rename api/kogito-api/src/main/java/org/kie/kogito/{process/workitem => usertask/model}/Comment.java (86%) rename {jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask => api/kogito-api/src/main/java/org/kie/kogito/usertask/model}/DeadlineInfo.java (97%) rename {jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask => api/kogito-api/src/main/java/org/kie/kogito/usertask/model}/Reassignment.java (97%) rename {jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask => api/kogito-api/src/main/java/org/kie/kogito/usertask/model}/ScheduleInfo.java (98%) create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/DefaultInstanceEventBatch.java delete mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AbstractDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AdapterHelper.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/DataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessCompletedEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessErrorEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessMigratedEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeEnteredEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeLeftEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessSLAEventDataEventAdapter.java rename jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/DoNothingWorkItemHandler.java => api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessStartedEventDataEventAdapter.java (61%) mode change 100755 => 100644 create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessVariableEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskAssignmentEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskCommentEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskDeadlineEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskStateEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskVariableEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTastAttachmentEventDataEventAdapter.java create mode 100644 api/kogito-events-core/src/main/resources/META-INF/services/org.kie.kogito.event.impl.adapter.DataEventAdapter delete mode 100755 jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ReceiveTaskHandler.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAttachmentEventImpl.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskCommentEventImpl.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskEventImpl.java delete mode 100755 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandler.java delete mode 100755 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandlerDialog.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/BaseHumanTaskLifeCycle.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskHelper.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskTransition.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemHandler.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemImpl.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/InternalHumanTaskWorkItem.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Claim.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Release.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Skip.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Abort.java delete mode 100644 jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Complete.java rename jbpm/{jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath => jbpm-flow/src/main/java/org/jbpm/workflow/core/impl}/XPATHAssignmentAction.java (59%) create mode 100644 jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestUserTaskWorkItemHandler.java create mode 100644 jbpm/jbpm-usertask/pom.xml rename {api/kogito-api/src/main/java/org/kie/kogito/process/workitem => jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler}/Policies.java (84%) create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerFactory.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTask.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskEventListenerConfig.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/KogitoUserTaskEventSupportImpl.java rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/event => jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events}/UserTaskAssignmentEventImpl.java (58%) create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAttachmentEventImpl.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskCommentEventImpl.java rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/event => jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events}/UserTaskDeadlineEventImpl.java (62%) create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskEventImpl.java rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/event => jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events}/UserTaskStateEventImpl.java (71%) rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/event => jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events}/UserTaskVariableEventImpl.java (80%) create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java create mode 100644 jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskTransitionToken.java rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Active.java => jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTransition.java} (50%) rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask => jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model}/DeadlineHelper.java (97%) create mode 100644 jbpm/jbpm-usertask/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory rename jbpm/{jbpm-flow/src/test/java/org/jbpm/process/instance/impl/humantask => jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model}/DeadlineHelperTest.java (98%) rename jbpm/{jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler => process-workitems/src/main/java/org/jbpm/process/workitem/builtin}/AbstractExceptionHandlingTaskHandler.java (60%) create mode 100644 jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DefaultKogitoWorkItemHandlerFactory.java create mode 100755 jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DoNothingWorkItemHandler.java rename jbpm/{jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler => process-workitems/src/main/java/org/jbpm/process/workitem/builtin}/LoggingTaskHandlerDecorator.java (95%) rename jbpm/{jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo => process-workitems/src/main/java/org/jbpm/process/workitem/builtin}/MockDataWorkItemHandler.java (69%) create mode 100755 jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ReceiveTaskHandler.java rename jbpm/{jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler => process-workitems/src/main/java/org/jbpm/process/workitem/builtin}/SendTaskHandler.java (56%) rename jbpm/{jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler => process-workitems/src/main/java/org/jbpm/process/workitem/builtin}/ServiceTaskHandler.java (81%) rename jbpm/{jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler => process-workitems/src/main/java/org/jbpm/process/workitem/builtin}/SignallingTaskHandlerDecorator.java (70%) create mode 100755 jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SystemOutWorkItemHandler.java create mode 100644 jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultKogitoWorkItemHandler.java create mode 100644 jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCycle.java create mode 100644 jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCyclePhase.java create mode 100644 jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemTransitionImpl.java create mode 100644 jbpm/process-workitems/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenFactory.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenHelper.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskConfigGenerator.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigJavaTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigQuarkusTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigSpringTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskJavaTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskQuarkusTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskSpringTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java create mode 100644 kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java create mode 100644 springboot/integration-tests/integration-tests-springboot-kafka-it/.gitignore create mode 100644 springboot/integration-tests/integration-tests-springboot-processes-it/.gitignore create mode 100644 springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/.gitignore diff --git a/addons/common/human-task-prediction/api/pom.xml b/addons/common/human-task-prediction/api/pom.xml index 7731d01c457..ac443d277b7 100644 --- a/addons/common/human-task-prediction/api/pom.xml +++ b/addons/common/human-task-prediction/api/pom.xml @@ -58,6 +58,10 @@ jbpm-deps-group-engine pom + + org.kie.kogito + jbpm-usertask + diff --git a/addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycle.java b/addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycle.java deleted file mode 100644 index 77240e0f345..00000000000 --- a/addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycle.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.kie.kogito.prediction.api; - -import java.util.Map; -import java.util.Objects; - -import org.jbpm.process.instance.impl.humantask.BaseHumanTaskLifeCycle; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.workitem.Active; -import org.jbpm.process.instance.impl.workitem.Complete; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Transition; -import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PredictionAwareHumanTaskLifeCycle extends BaseHumanTaskLifeCycle { - - private static final Logger logger = LoggerFactory.getLogger(PredictionAwareHumanTaskLifeCycle.class); - - private PredictionService predictionService; - - public PredictionAwareHumanTaskLifeCycle(PredictionService predictionService) { - this.predictionService = Objects.requireNonNull(predictionService); - } - - @Override - public Map transitionTo(KogitoWorkItem workItem, KogitoWorkItemManager manager, Transition> transition) { - LifeCyclePhase targetPhase = phaseById(transition.phase()); - if (targetPhase == null) { - logger.debug("Target life cycle phase '{}' does not exist in {}", transition.phase(), this.getClass().getSimpleName()); - throw new InvalidLifeCyclePhaseException(transition.phase()); - } - - InternalHumanTaskWorkItem humanTaskWorkItem = (InternalHumanTaskWorkItem) workItem; - if (targetPhase.id().equals(Active.ID)) { - - PredictionOutcome outcome = predictionService.predict(workItem, workItem.getParameters()); - logger.debug("Prediction service returned confidence level {} for work item {}", outcome.getConfidenceLevel(), humanTaskWorkItem.getStringId()); - - if (outcome.isCertain()) { - humanTaskWorkItem.setResults(outcome.getData()); - logger.debug("Prediction service is certain (confidence level {}) on the outputs, completing work item {}", outcome.getConfidenceLevel(), humanTaskWorkItem.getStringId()); - ((InternalKogitoWorkItemManager) manager).internalCompleteWorkItem(humanTaskWorkItem); - - return outcome.getData(); - } else if (outcome.isPresent()) { - logger.debug("Prediction service is NOT certain (confidence level {}) on the outputs, setting recommended outputs on work item {}", outcome.getConfidenceLevel(), - humanTaskWorkItem.getStringId()); - humanTaskWorkItem.setResults(outcome.getData()); - - } - } - - // prediction service does work only on activating tasks - Map data = super.transitionTo(workItem, manager, transition); - if (targetPhase.id().equals(Complete.ID)) { - // upon actual transition train the data if it's completion phase - predictionService.train(humanTaskWorkItem, workItem.getParameters(), data); - } - return data; - } - -} diff --git a/addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskWorkItemHandler.java b/addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskWorkItemHandler.java new file mode 100644 index 00000000000..5b99b8a6c95 --- /dev/null +++ b/addons/common/human-task-prediction/api/src/main/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskWorkItemHandler.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.prediction.api; + +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PredictionAwareHumanTaskWorkItemHandler extends DefaultKogitoWorkItemHandler { + + private static final Logger logger = LoggerFactory.getLogger(PredictionAwareHumanTaskWorkItemHandler.class); + + private PredictionService predictionService; + + public PredictionAwareHumanTaskWorkItemHandler(PredictionService predictionService) { + this.predictionService = predictionService; + } + + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + PredictionOutcome outcome = predictionService.predict(workItem, workItem.getParameters()); + logger.debug("Prediction service returned confidence level {} for work item {}", outcome.getConfidenceLevel(), workItem.getStringId()); + + if (outcome.isCertain()) { + workItem.setOutputs(outcome.getData()); + logger.debug("Prediction service is certain (confidence level {}) on the outputs, completing work item {}", outcome.getConfidenceLevel(), workItem.getStringId()); + + return Optional.of(this.newTransition("skip", workItem.getPhaseStatus(), outcome.getData())); + } else if (outcome.isPresent()) { + logger.debug("Prediction service is NOT certain (confidence level {}) on the outputs, setting recommended outputs on work item {}", + outcome.getConfidenceLevel(), + workItem.getStringId()); + workItem.setOutputs(outcome.getData()); + } + return Optional.empty(); + } + + public Optional completeWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + // upon actual transition train the data if it's completion phase + predictionService.train(workItem, workItem.getParameters(), transition.data()); + return Optional.empty(); + } + +} diff --git a/addons/common/human-task-prediction/api/src/test/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycleTest.java b/addons/common/human-task-prediction/api/src/test/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycleTest.java index f8de462112e..d853d0d60fb 100644 --- a/addons/common/human-task-prediction/api/src/test/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycleTest.java +++ b/addons/common/human-task-prediction/api/src/test/java/org/kie/kogito/prediction/api/PredictionAwareHumanTaskLifeCycleTest.java @@ -25,11 +25,11 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.drools.io.ClassPathResource; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.kie.kogito.Model; import org.kie.kogito.auth.SecurityPolicy; +import org.kie.kogito.internal.process.workitem.Policy; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.WorkItem; @@ -38,7 +38,6 @@ import org.kie.kogito.process.impl.CachedWorkItemHandlerConfig; import org.kie.kogito.process.impl.DefaultProcessEventListenerConfig; import org.kie.kogito.process.impl.StaticProcessConfig; -import org.kie.kogito.process.workitem.Policy; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.services.identity.StaticIdentityProvider; import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory; @@ -50,7 +49,7 @@ public class PredictionAwareHumanTaskLifeCycleTest { - private Policy securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john")); + private Policy securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john")); private AtomicBoolean predictNow; private List trainedTasks; @@ -88,7 +87,7 @@ public String getIdentifier() { }; CachedWorkItemHandlerConfig wiConfig = new CachedWorkItemHandlerConfig(); - wiConfig.register("Human Task", new HumanTaskWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService))); + wiConfig.register("Human Task", new PredictionAwareHumanTaskWorkItemHandler(predictionService)); config = new StaticProcessConfig(wiConfig, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())); } diff --git a/addons/common/human-task-prediction/smile/src/main/java/org/kie/kogito/predictions/smile/SmileRandomForest.java b/addons/common/human-task-prediction/smile/src/main/java/org/kie/kogito/predictions/smile/SmileRandomForest.java index 28aefa704e9..bedb1bf0923 100644 --- a/addons/common/human-task-prediction/smile/src/main/java/org/kie/kogito/predictions/smile/SmileRandomForest.java +++ b/addons/common/human-task-prediction/smile/src/main/java/org/kie/kogito/predictions/smile/SmileRandomForest.java @@ -28,7 +28,7 @@ import java.util.Set; import org.kie.api.runtime.process.WorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.prediction.api.PredictionOutcome; import org.kie.kogito.prediction.api.PredictionService; import org.slf4j.Logger; diff --git a/addons/common/human-task-prediction/smile/src/test/java/org/kie/kogito/predictions/smile/SmileRandomForestPredictionTest.java b/addons/common/human-task-prediction/smile/src/test/java/org/kie/kogito/predictions/smile/SmileRandomForestPredictionTest.java index 42e05a9dc98..5b952bdeaa3 100644 --- a/addons/common/human-task-prediction/smile/src/test/java/org/kie/kogito/predictions/smile/SmileRandomForestPredictionTest.java +++ b/addons/common/human-task-prediction/smile/src/test/java/org/kie/kogito/predictions/smile/SmileRandomForestPredictionTest.java @@ -23,11 +23,10 @@ import java.util.Map; import org.drools.io.ClassPathResource; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.kie.kogito.Model; -import org.kie.kogito.prediction.api.PredictionAwareHumanTaskLifeCycle; +import org.kie.kogito.prediction.api.PredictionAwareHumanTaskWorkItemHandler; import org.kie.kogito.prediction.api.PredictionService; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; @@ -64,7 +63,7 @@ public void configure() { predictionService = new SmileRandomForest(configuration); CachedWorkItemHandlerConfig wiConfig = new CachedWorkItemHandlerConfig(); - wiConfig.register("Human Task", new HumanTaskWorkItemHandler(new PredictionAwareHumanTaskLifeCycle(predictionService))); + wiConfig.register("Human Task", new PredictionAwareHumanTaskWorkItemHandler(predictionService)); config = new StaticProcessConfig(wiConfig, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())); for (int i = 0; i < 10; i++) { @@ -77,7 +76,6 @@ public void configure() { @Test public void testUserTaskWithPredictionService() { - BpmnProcess process = (BpmnProcess) BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.configure(); diff --git a/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java b/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java index 155bb5884fb..2106596a220 100644 --- a/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java +++ b/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java @@ -37,10 +37,13 @@ import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; -import org.kie.kogito.services.identity.StaticIdentityProvider; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kie.kogito.uow.UnitOfWork; import org.kie.kogito.uow.UnitOfWorkManager; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.entry; @@ -59,10 +62,12 @@ class FileSystemProcessInstancesTest { - private SecurityPolicy securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john")); + private SecurityPolicy securityPolicy = SecurityPolicy.of("john", emptyList()); private BpmnProcess createProcess(String fileName) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource(fileName)).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource(fileName)).get(0); process.setProcessInstancesFactory(new FileSystemProcessInstancesFactory()); process.configure(); abort(process.instances()); diff --git a/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesIT.java b/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesIT.java index 19df9516d5d..df25d74aef5 100644 --- a/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesIT.java +++ b/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesIT.java @@ -39,11 +39,14 @@ import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; -import org.kie.kogito.services.identity.StaticIdentityProvider; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kie.kogito.testcontainers.KogitoInfinispanContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.entry; @@ -82,7 +85,9 @@ void close() { @Test void testFindByIdReadMode() { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask-Script.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask-Script.bpmn2")).get(0); // workaround as BpmnProcess does not compile the scripts but just reads the xml for (Node node : ((WorkflowProcess) process.get()).getNodes()) { if (node instanceof ActionNode) { @@ -126,7 +131,9 @@ void testFindByIdReadMode() { @Test void testValuesReadMode() { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(new CacheProcessInstancesFactory(cacheManager)); process.configure(); @@ -143,7 +150,9 @@ void testValuesReadMode() { @Test void testBasicFlow() { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(new CacheProcessInstancesFactory(cacheManager)); process.configure(); @@ -154,7 +163,7 @@ void testBasicFlow() { assertOne(process.instances()); - SecurityPolicy asJohn = SecurityPolicy.of(new StaticIdentityProvider("john")); + SecurityPolicy asJohn = SecurityPolicy.of("john", emptyList()); assertThat(getFirst(process.instances()).workItems(asJohn)).hasSize(1); diff --git a/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java b/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java index 77b4c8429e8..d82a2505531 100644 --- a/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java +++ b/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java @@ -33,6 +33,9 @@ import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; import org.kie.kogito.process.impl.AbstractProcessInstance; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kie.kogito.testcontainers.KogitoInfinispanContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -71,7 +74,9 @@ void close() { } private BpmnProcess createProcess(String fileName) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource(fileName)).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource(fileName)).get(0); AbstractProcessInstancesFactory factory = mock(AbstractProcessInstancesFactory.class); process.setProcessInstancesFactory(factory); process.configure(); @@ -80,6 +85,8 @@ private BpmnProcess createProcess(String fileName) { @Test public void testBasic() { + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); BpmnProcess process = createProcess("BPMN2-UserTask.bpmn2"); CacheProcessInstances pi = new CacheProcessInstances(process, cacheManager, null, true); diff --git a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java index 4a2e47132bf..981114c5df7 100644 --- a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java +++ b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java @@ -30,12 +30,16 @@ import org.junit.jupiter.api.Test; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; +import org.kie.kogito.internal.process.workitem.Policy; import org.kie.kogito.persistence.jdbc.JDBCProcessInstances; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnProcessInstance; import org.kie.kogito.process.bpmn2.BpmnVariables; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.testcontainers.containers.JdbcDatabaseContainer; import static java.util.Collections.singletonMap; @@ -56,7 +60,7 @@ abstract class AbstractProcessInstancesIT { public static final String TEST_ID = "02ac3854-46ee-42b7-8b63-5186c9889d96"; - public static SecurityPolicy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john")); + public static Policy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john")); DataSource dataSource; @@ -69,7 +73,9 @@ public static void initMigration(JdbcDatabaseContainer container, String dbKind) } public static BpmnProcess createProcess(TestProcessInstancesFactory factory, String fileName) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource(fileName)).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource(fileName)).get(0); process.setProcessInstancesFactory(factory); process.configure(); abort(process.instances()); diff --git a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/MongoDBProcessInstancesIT.java b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/MongoDBProcessInstancesIT.java index 3ea36ffaf69..40f1f9fa868 100644 --- a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/MongoDBProcessInstancesIT.java +++ b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/MongoDBProcessInstancesIT.java @@ -44,7 +44,9 @@ import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; -import org.kie.kogito.services.identity.StaticIdentityProvider; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kie.kogito.testcontainers.KogitoMongoDBContainer; import org.kie.kogito.uow.events.UnitOfWorkEndEvent; import org.kie.kogito.uow.events.UnitOfWorkStartEvent; @@ -55,6 +57,7 @@ import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.entry; @@ -70,7 +73,7 @@ @Testcontainers class MongoDBProcessInstancesIT { - private SecurityPolicy securityPolicy = SecurityPolicy.of(new StaticIdentityProvider("john")); + private SecurityPolicy securityPolicy = SecurityPolicy.of("john", emptyList()); @Container final static KogitoMongoDBContainer mongoDBContainer = new KogitoMongoDBContainer(); @@ -113,7 +116,9 @@ void testWithTransaction() { } private void test(AbstractTransactionManager transactionManager) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(new MongoDBProcessInstancesFactory(mongoClient, transactionManager)); process.configure(); @@ -200,7 +205,9 @@ void testFindByIdReadModeWithTransaction() { } void testFindByIdReadMode(AbstractTransactionManager transactionManager) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask-Script.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask-Script.bpmn2")).get(0); // workaround as BpmnProcess does not compile the scripts but just reads the xml for (Node node : ((WorkflowProcess) process.get()).getNodes()) { if (node instanceof ActionNode) { @@ -260,7 +267,9 @@ void testValuesReadModeWithTransaction() { } void testValuesReadMode(AbstractTransactionManager transactionManager) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(new MongoDBProcessInstancesFactory(mongoClient, transactionManager)); process.configure(); diff --git a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java index 97e1de86843..e64489128b9 100644 --- a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java +++ b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java @@ -34,6 +34,9 @@ import org.kie.kogito.process.bpmn2.BpmnProcessInstance; import org.kie.kogito.process.bpmn2.BpmnVariables; import org.kie.kogito.process.impl.AbstractProcessInstance; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import com.mongodb.client.ClientSession; import com.mongodb.client.FindIterable; @@ -63,7 +66,9 @@ class PersistentProcessInstancesIT extends TestHelper { void testMongoDBPersistence() { MongoDBProcessInstancesFactory factory = new MongoDBProcessInstancesFactory(getMongoClient(), getDisabledMongoDBTransactionManager()); - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(factory); process.configure(); @@ -121,7 +126,9 @@ void testMongoDBPersistenceWithTransaction() { String id = "testId"; - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(new MongoDBProcessInstancesFactory(getMongoClient(), transactionExecutor)); process.configure(); diff --git a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesWithLockIT.java b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesWithLockIT.java index 74d49f2dc88..d97213e97a2 100644 --- a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesWithLockIT.java +++ b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesWithLockIT.java @@ -27,6 +27,9 @@ import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnProcessInstance; import org.kie.kogito.process.bpmn2.BpmnVariables; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; @@ -36,7 +39,9 @@ class PersistentProcessInstancesWithLockIT extends TestHelper { private BpmnProcess createProcess(MongoDBProcessInstancesFactory factory) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); process.setProcessInstancesFactory(factory); process.configure(); return process; diff --git a/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java b/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java index 716c909cec6..7948364084f 100644 --- a/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java +++ b/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java @@ -37,6 +37,9 @@ import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnProcessInstance; import org.kie.kogito.process.bpmn2.BpmnVariables; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kie.kogito.testcontainers.KogitoPostgreSqlContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -88,7 +91,9 @@ boolean lock() { } private BpmnProcess createProcess(String fileName) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource(fileName)).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource(fileName)).get(0); process.setProcessInstancesFactory(new PostgreProcessInstancesFactory(client, lock())); process.configure(); abort(process.instances()); diff --git a/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java b/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java index 7f07fb32bc4..89d1eb58263 100644 --- a/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java +++ b/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java @@ -44,6 +44,9 @@ import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; import org.kie.kogito.process.impl.AbstractProcessInstance; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.rocksdb.Options; import org.rocksdb.RocksDBException; import org.slf4j.Logger; @@ -88,7 +91,9 @@ static void cleanUp() { } private BpmnProcess createProcess(String fileName) { - BpmnProcess process = BpmnProcess.from(new ClassPathResource(fileName)).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource(fileName)).get(0); process.setProcessInstancesFactory(factory); process.configure(); return process; diff --git a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java index 64c56c8d20b..43514088cf5 100644 --- a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java +++ b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java @@ -31,7 +31,6 @@ import org.jbpm.workflow.core.WorkflowProcess; import org.kie.kogito.Application; import org.kie.kogito.Model; -import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessError; @@ -158,9 +157,7 @@ public T doGetWorkItemsInProcessInstance(String processId, String processInstanc return executeOnProcessInstance(processId, processInstanceId, processInstance -> { // use special security policy to bypass auth check as this is management operation - List workItems = processInstance.workItems(new SecurityPolicy(null) { - }); - + List workItems = processInstance.workItems(); return buildOkResponse(workItems); }); } diff --git a/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java b/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java index d58a3f10dfe..154bb463082 100644 --- a/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java +++ b/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java @@ -32,7 +32,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.kie.kogito.Application; -import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.process.ProcessError; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.ProcessInstances; @@ -260,7 +259,7 @@ void testDoGetInstanceInError() { @Test void testDoGetWorkItemsInProcessInstance(@Mock WorkItem workItem) { - when(processInstance.workItems(any(SecurityPolicy.class))).thenReturn(singletonList(workItem)); + when(processInstance.workItems()).thenReturn(singletonList(workItem)); Object response = tested.doGetWorkItemsInProcessInstance(PROCESS_ID, PROCESS_INSTANCE_ID); assertThat(response).isInstanceOf(List.class); assertThat(((List) response).get(0)).isEqualTo(workItem); diff --git a/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java b/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java index 6ea4f90d3e8..cdd3b2ad524 100644 --- a/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java +++ b/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java @@ -23,17 +23,17 @@ import java.util.Map; import java.util.function.Function; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.InvalidLifeCyclePhaseException; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; import org.kie.kogito.process.NodeInstanceNotFoundException; import org.kie.kogito.process.NodeNotFoundException; import org.kie.kogito.process.ProcessInstanceDuplicatedException; import org.kie.kogito.process.ProcessInstanceExecutionException; import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.VariableViolationException; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; -import org.kie.kogito.process.workitem.InvalidTransitionException; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.WorkItemExecutionException; public abstract class BaseExceptionsHandler { diff --git a/addons/common/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/BaseExceptionHandlerTest.java b/addons/common/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/BaseExceptionHandlerTest.java index 7e385e2183b..01f244915df 100644 --- a/addons/common/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/BaseExceptionHandlerTest.java +++ b/addons/common/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/BaseExceptionHandlerTest.java @@ -21,16 +21,16 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.InvalidLifeCyclePhaseException; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; import org.kie.kogito.process.NodeInstanceNotFoundException; import org.kie.kogito.process.ProcessInstanceDuplicatedException; import org.kie.kogito.process.ProcessInstanceExecutionException; import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.VariableViolationException; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; -import org.kie.kogito.process.workitem.InvalidTransitionException; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.WorkItemExecutionException; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; diff --git a/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementOperations.java b/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementOperations.java index 085589276a7..6e5f7711d86 100644 --- a/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementOperations.java +++ b/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementOperations.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.task.management.service; -import org.kie.kogito.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.Policy; public interface TaskManagementOperations { @@ -27,7 +27,7 @@ TaskInfo updateTask(String processId, String taskId, TaskInfo taskInfo, boolean replace, - Policy... policies); + Policy... policies); - TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies); + TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies); } diff --git a/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementService.java b/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementService.java index 964d26646e6..450dc30d0b1 100644 --- a/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementService.java +++ b/addons/common/task-management/src/main/java/org/kie/kogito/task/management/service/TaskManagementService.java @@ -18,22 +18,22 @@ */ package org.kie.kogito.task.management.service; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Supplier; -import org.jbpm.process.instance.impl.humantask.HumanTaskHelper; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.Policy; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.Processes; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.Policy; +import org.kie.kogito.process.WorkItem; +import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.services.uow.UnitOfWorkExecutor; public class TaskManagementService implements TaskManagementOperations { @@ -52,24 +52,16 @@ public TaskInfo updateTask(String processId, String taskId, TaskInfo taskInfo, boolean shouldReplace, - Policy... policies) { + Policy... policies) { ProcessInstance pi = getProcessInstance(processId, processInstanceId, taskId); KogitoWorkItem workItem = UnitOfWorkExecutor.executeInUnitOfWork(processConfig.unitOfWorkManager(), () -> pi.updateWorkItem(taskId, wi -> { - InternalHumanTaskWorkItem humanTask = HumanTaskHelper.asHumanTask(wi); - setField(humanTask::setAdminGroups, taskInfo::getAdminGroups, shouldReplace); - setField(humanTask::setAdminUsers, taskInfo::getAdminUsers, shouldReplace); - setField(humanTask::setExcludedUsers, taskInfo::getExcludedUsers, shouldReplace); - setField(humanTask::setPotentialUsers, taskInfo::getPotentialUsers, shouldReplace); - setField(humanTask::setPotentialGroups, taskInfo::getPotentialGroups, shouldReplace); - setField(humanTask::setTaskPriority, taskInfo::getPriority, shouldReplace); - setField(humanTask::setTaskDescription, taskInfo::getDescription, shouldReplace); - setMap(humanTask::setParameters, humanTask::setParameter, taskInfo.getInputParams(), - shouldReplace); + InternalKogitoWorkItem task = (InternalKogitoWorkItem) wi; + setMap(task::setParameters, task::setParameter, taskInfo.getInputParams(), shouldReplace); return wi; }, policies)); - return convert((HumanTaskWorkItem) workItem); + return convert(workItem); } private void setMap(Consumer> allConsumer, @@ -87,25 +79,44 @@ private void setMap(Consumer> allConsumer, } } - private boolean setField(Consumer consumer, Supplier supplier, boolean shouldReplace) { - T value = supplier.get(); - boolean result = shouldReplace || value != null; - if (result) { - consumer.accept(value); - } - return result; + @Override + public TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies) { + WorkItem workItem = getProcessInstance(processId, processInstanceId, taskId).workItem(taskId, policies); + return convert(workItem); } - @Override - public TaskInfo getTask(String processId, String processInstanceId, String taskId, Policy... policies) { - return convert(HumanTaskHelper.findTask(getProcessInstance(processId, processInstanceId, taskId), taskId, - policies)); + private TaskInfo convert(WorkItem workItem) { + return new TaskInfo( + (String) workItem.getParameters().get("Description"), + (String) workItem.getParameters().get("Priority"), + toSet(workItem.getParameters().get("ActorId")), + toSet(workItem.getParameters().get("GroupId")), + toSet(workItem.getParameters().get("ExcludedUsersId")), + toSet(workItem.getParameters().get("BusinessAdministratorId")), + toSet(workItem.getParameters().get("BusinessGroupsId")), + workItem.getParameters()); + } + + private TaskInfo convert(KogitoWorkItem workItem) { + return new TaskInfo( + (String) workItem.getParameter("Description"), + (String) workItem.getParameter("Priority"), + toSet(workItem.getParameter("ActorId")), + toSet(workItem.getParameter("GroupId")), + toSet(workItem.getParameter("ExcludedUsersId")), + toSet(workItem.getParameter("BusinessAdministratorId")), + toSet(workItem.getParameter("BusinessGroupsId")), + workItem.getParameters()); } - private TaskInfo convert(HumanTaskWorkItem humanTask) { - return new TaskInfo(humanTask.getTaskDescription(), humanTask.getTaskPriority(), humanTask.getPotentialUsers(), - humanTask.getPotentialGroups(), humanTask.getExcludedUsers(), humanTask.getAdminUsers(), - humanTask.getAdminGroups(), humanTask.getParameters()); + private Set toSet(Object value) { + if (value == null) { + return Collections.emptySet(); + } + if (value instanceof String string) { + return Set.of(string.split(",")); + } + return Collections.emptySet(); } private ProcessInstance getProcessInstance(String processId, String processInstanceId, String taskId) { @@ -125,4 +136,5 @@ private ProcessInstance getProcessInstance(String processId, String processIn return process.instances().findById(processInstanceId).orElseThrow( () -> new ProcessInstanceNotFoundException(processInstanceId)); } + } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/auth/SecurityPolicy.java b/api/kogito-api/src/main/java/org/kie/kogito/auth/SecurityPolicy.java index 3efb75a2dd4..a32ef609c1c 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/auth/SecurityPolicy.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/auth/SecurityPolicy.java @@ -18,17 +18,25 @@ */ package org.kie.kogito.auth; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Objects; -import org.kie.kogito.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; +import org.kie.kogito.internal.process.workitem.Policy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Security policy that delivers IdentityProvider to allow to security * related policy enforcement. * */ -public class SecurityPolicy implements Policy { +public class SecurityPolicy implements Policy { + + private static final Logger LOGGER = LoggerFactory.getLogger(SecurityPolicy.class); private IdentityProvider identity; @@ -55,9 +63,46 @@ protected SecurityPolicy(IdentityProvider identity) { this.identity = identity; } + public String getUser() { + return identity.getName(); + } + + public Collection getRoles() { + return identity.getRoles(); + } + + @Override + public void enforce(KogitoWorkItem workItem) { + if (workItem.getActualOwner() != null && workItem.getActualOwner().equals(getUser())) { + return; + } + + String actualOwner = workItem.getActualOwner(); + String actualOwners = (String) workItem.getParameter("ActorId"); + String actualRoles = (String) workItem.getParameter("GroupId"); + String excludedOwner = (String) workItem.getParameter("ExcludedOwnerId"); + if (actualOwners != null || actualRoles != null) { + List owners = actualOwners != null ? new ArrayList<>(List.of(actualOwners.split(","))) : new ArrayList<>(); + List excluded = excludedOwner != null ? new ArrayList<>(List.of(excludedOwner.split(","))) : new ArrayList<>(); + owners.removeAll(excluded); + List roles = actualRoles != null ? List.of(actualRoles.split(",")) : new ArrayList<>(); + List userRoles = new ArrayList<>(identity.getRoles()); + userRoles.retainAll(roles); + LOGGER.debug("enforcing identity {} and roles {} with potential owners {} and potential groups {} and exclude groups {}", + identity.getName(), identity.getRoles(), owners, roles, excluded); + if (!owners.contains(identity.getName()) && userRoles.isEmpty()) { + LOGGER.debug("not authorized with owner {} against identity {}", actualOwner, identity.getName()); + throw new NotAuthorizedException("this work item " + workItem.getStringId() + " is not allows by this owner " + actualOwners + " or " + actualRoles); + } else if (userRoles.isEmpty() && actualOwner != null && !identity.getName().equals(actualOwner)) { + LOGGER.debug("identity {} with roles {} not authorized in {}", identity.getName(), identity.getRoles(), roles); + throw new NotAuthorizedException("this work item " + workItem.getStringId() + " is not allows by this owner " + actualOwner); + } + } + } + @Override - public IdentityProvider value() { - return identity; + public String toString() { + return "SecurityPolicy [identity=" + identity.getName() + ", roles=" + identity.getRoles() + "]"; } } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventListener.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventListener.java index fdb2fd88d25..5bdbb74b780 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventListener.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventListener.java @@ -19,12 +19,6 @@ package org.kie.kogito.internal.process.event; import org.kie.api.event.process.ProcessEventListener; -import org.kie.api.event.usertask.UserTaskAssignmentEvent; -import org.kie.api.event.usertask.UserTaskAttachmentEvent; -import org.kie.api.event.usertask.UserTaskCommentEvent; -import org.kie.api.event.usertask.UserTaskDeadlineEvent; -import org.kie.api.event.usertask.UserTaskStateEvent; -import org.kie.api.event.usertask.UserTaskVariableEvent; public interface KogitoProcessEventListener extends ProcessEventListener { @@ -43,50 +37,4 @@ default void beforeWorkItemTransition(ProcessWorkItemTransitionEvent event) { */ default void afterWorkItemTransition(ProcessWorkItemTransitionEvent event) { } - - // for user tasks - - default void onUserTaskDeadline(UserTaskDeadlineEvent event) { - // nothing - } - - default void onUserTaskState(UserTaskStateEvent event) { - // nothing - } - - default void onUserTaskAssignment(UserTaskAssignmentEvent event) { - // nothing - } - - default void onUserTaskInputVariable(UserTaskVariableEvent event) { - // nothing - } - - default void onUserTaskOutputVariable(UserTaskVariableEvent event) { - // nothing - } - - default void onUserTaskAttachmentAdded(UserTaskAttachmentEvent event) { - // nothing - } - - default void onUserTaskAttachmentDeleted(UserTaskAttachmentEvent event) { - // nothing - } - - default void onUserTaskAttachmentChange(UserTaskAttachmentEvent event) { - // nothing - } - - default void onUserTaskCommentChange(UserTaskCommentEvent event) { - // nothing - } - - default void onUserTaskCommentAdded(UserTaskCommentEvent event) { - // nothing - } - - default void onUserTaskCommentDeleted(UserTaskCommentEvent event) { - // nothing - } } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java index 89539f60d02..573f67c0125 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java @@ -19,17 +19,12 @@ package org.kie.kogito.internal.process.event; import java.util.List; -import java.util.Map; -import java.util.Set; import org.kie.api.runtime.KieRuntime; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.Transition; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; public interface KogitoProcessEventSupport { @@ -63,9 +58,9 @@ void fireAfterVariableChanged(String name, String id, Object oldValue, Object ne void fireAfterSLAViolated(KogitoProcessInstance instance, KogitoNodeInstance nodeInstance, KieRuntime kruntime); - void fireBeforeWorkItemTransition(KogitoProcessInstance instance, KogitoWorkItem workitem, Transition transition, KieRuntime kruntime); + void fireBeforeWorkItemTransition(KogitoProcessInstance instance, KogitoWorkItem workitem, WorkItemTransition transition, KieRuntime kruntime); - void fireAfterWorkItemTransition(KogitoProcessInstance instance, KogitoWorkItem workitem, Transition transition, KieRuntime kruntime); + void fireAfterWorkItemTransition(KogitoProcessInstance instance, KogitoWorkItem workitem, WorkItemTransition transition, KieRuntime kruntime); void fireOnSignal(KogitoProcessInstance instance, KogitoNodeInstance nodeInstance, KieRuntime kruntime, String signalName, Object signalObject); @@ -75,93 +70,6 @@ void fireAfterVariableChanged(String name, String id, Object oldValue, Object ne void fireOnMigration(KogitoProcessInstance processInstance, KieRuntime runtime); - // user tasks events - - void fireOneUserTaskStateChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - String oldPhaseStatus, String newPhaseStatus); - - void fireOnUserTaskNotStartedDeadline( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - HumanTaskWorkItem workItem, - Map notification, - KieRuntime kruntime); - - void fireOnUserTaskNotCompletedDeadline( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - HumanTaskWorkItem workItem, - Map notification, - KieRuntime kruntime); - - enum AssignmentType { - USER_OWNERS, - USER_GROUPS, - USERS_EXCLUDED, - ADMIN_GROUPS, - ADMIN_USERS - }; - - void fireOnUserTaskAssignmentChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - AssignmentType assignmentType, - Set oldUsersId, Set newUsersId); - - void fireOnUserTaskInputVariableChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - String variableName, - Object newValue, Object oldValue); - - void fireOnUserTaskOutputVariableChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - String variableName, - Object newValue, Object oldValue); - - void fireOnUserTaskAttachmentAdded( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Attachment addedAttachment); - - void fireOnUserTaskAttachmentDeleted( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Attachment deletedAttachment); - - void fireOnUserTaskAttachmentChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Attachment oldAttachment, Attachment newAttachment); - - void fireOnUserTaskCommentChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Comment oldComment, Comment newComment); - - void fireOnUserTaskCommentDeleted( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Comment deletedComment); - - void fireOnUserTaskCommentAdded( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Comment addedComment); - void reset(); void addEventListener(KogitoProcessEventListener listener); diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/ProcessWorkItemTransitionEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/ProcessWorkItemTransitionEvent.java index 08b65ea1630..79a1030acd1 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/ProcessWorkItemTransitionEvent.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/ProcessWorkItemTransitionEvent.java @@ -19,15 +19,13 @@ package org.kie.kogito.internal.process.event; import org.kie.api.event.process.ProcessEvent; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.Transition; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; /** * An event when a work item has transition between life cycle phases */ -public interface ProcessWorkItemTransitionEvent - extends - ProcessEvent { +public interface ProcessWorkItemTransitionEvent extends ProcessEvent { /** * Returns work item being transitioned @@ -41,7 +39,7 @@ public interface ProcessWorkItemTransitionEvent * * @return transition */ - Transition getTransition(); + WorkItemTransition getTransition(); /** * Indicated is the transition has already been done. diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoProcessRuntime.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoProcessRuntime.java index 10c14e9883d..a7011eb42ee 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoProcessRuntime.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoProcessRuntime.java @@ -28,6 +28,7 @@ import org.kie.api.runtime.rule.AgendaFilter; import org.kie.kogito.Application; import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; import org.kie.kogito.jobs.JobsService; public interface KogitoProcessRuntime { diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemNodeInstance.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemNodeInstance.java index 16538189e8f..856f0f15674 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemNodeInstance.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemNodeInstance.java @@ -18,6 +18,8 @@ */ package org.kie.kogito.internal.process.runtime; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; + public interface KogitoWorkItemNodeInstance extends KogitoNodeInstance { KogitoWorkItem getWorkItem(); diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/InvalidLifeCyclePhaseException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/InvalidLifeCyclePhaseException.java similarity index 95% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/InvalidLifeCyclePhaseException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/InvalidLifeCyclePhaseException.java index e0fbd9d8982..e8facfd20a8 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/InvalidLifeCyclePhaseException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/InvalidLifeCyclePhaseException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; /** * Thrown when there is no such life cycle phase diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/InvalidTransitionException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/InvalidTransitionException.java similarity index 95% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/InvalidTransitionException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/InvalidTransitionException.java index 2d52514b088..537f4c801e1 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/InvalidTransitionException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/InvalidTransitionException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; /** * Thrown when given work item transition cannot be performed diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItem.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItem.java similarity index 80% rename from api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItem.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItem.java index bfb87d82d25..e559ae738ce 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItem.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItem.java @@ -16,19 +16,27 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.internal.process.runtime; +package org.kie.kogito.internal.process.workitem; import java.util.Date; +import java.util.Map; import org.kie.api.runtime.process.WorkItem; -import org.kie.kogito.process.workitem.Policy; +import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; +import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; public interface KogitoWorkItem extends WorkItem { + static final String PARAMETER_UNIQUE_TASK_ID = "UNIQUE_TASK_ID"; + @Override @Deprecated long getId(); + String getExternalReferenceId(); + + String getActualOwner(); + String getStringId(); /** @@ -83,14 +91,11 @@ public interface KogitoWorkItem extends WorkItem { */ KogitoProcessInstance getProcessInstance(); - /** - * Enforces given policies on this work item. It must false in case of any policy - * violations. - * - * @param policies optional policies to be enforced - * @return return true if this work item can enforce all policies otherwise false - */ - default boolean enforce(Policy... policies) { - return true; + void removeOutput(String name); + + void setOutput(String name, Object value); + + default void setOutputs(Map outputs) { + outputs.forEach(this::setOutput); } } \ No newline at end of file diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemHandler.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandler.java similarity index 55% rename from api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemHandler.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandler.java index df5399c49ef..3f131a46081 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemHandler.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandler.java @@ -16,27 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.internal.process.runtime; +package org.kie.kogito.internal.process.workitem; -import org.kie.kogito.process.workitem.Transition; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.kie.kogito.Application; public interface KogitoWorkItemHandler { /** - * The given work item should be executed. - * - * @param workItem the work item that should be executed - * @param manager the manager that requested the work item to be executed + * This will allow access other part of the system. + * + * @return */ - void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager); + Application getApplication(); - /** - * The given work item should be aborted. - * - * @param workItem the work item that should be aborted - * @param manager the manager that requested the work item to be aborted - */ - void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager); + void setApplication(Application app); /** * Returns name that it should be registered with, by default simple class name; @@ -47,7 +44,25 @@ default String getName() { return getClass().getSimpleName(); } - default void transitionToPhase(KogitoWorkItem workItem, KogitoWorkItemManager manager, Transition transition) { - throw new UnsupportedOperationException(); - } + /* + * Transition to another phase from initial + */ + Optional transitionToPhase(KogitoWorkItemManager manager, KogitoWorkItem workItem, WorkItemTransition transition); + + Set allowedTransitions(String phaseStatus); + + WorkItemTransition newTransition(String phaseId, String phaseStatus, Map map, Policy... policy); + + /** + * The given work item should be activate. + * + * @param workItem the work item that should be executed + * @param manager the manager that requested the work item to be executed + */ + WorkItemTransition startingTransition(Map data, Policy... policies); + + WorkItemTransition completeTransition(String phaseStatus, Map data, Policy... policies); + + WorkItemTransition abortTransition(String phaseStatus, Policy... policies); + } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerFactory.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerFactory.java new file mode 100644 index 00000000000..0b9438bb8c1 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerFactory.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.internal.process.workitem; + +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; + +public interface KogitoWorkItemHandlerFactory { + + public static List findAllKogitoWorkItemHandlersRegistered() { + List handlers = new ArrayList<>(); + ServiceLoader.load(KogitoWorkItemHandlerFactory.class).stream() + .map(ServiceLoader.Provider::get) + .map(KogitoWorkItemHandlerFactory::provide) + .flatMap(List::stream) + .forEach(e -> handlers.add(e)); + return handlers; + } + + List provide(); + +} diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/KogitoWorkItemHandlerNotFoundException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerNotFoundException.java similarity index 95% rename from jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/KogitoWorkItemHandlerNotFoundException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerNotFoundException.java index d0d64d410d4..622ee908de1 100755 --- a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/KogitoWorkItemHandlerNotFoundException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemHandlerNotFoundException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitems; +package org.kie.kogito.internal.process.workitem; public class KogitoWorkItemHandlerNotFoundException extends RuntimeException { diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemManager.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemManager.java similarity index 74% rename from api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemManager.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemManager.java index 0be48e886f3..7e384ec35f3 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkItemManager.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/KogitoWorkItemManager.java @@ -16,14 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.internal.process.runtime; +package org.kie.kogito.internal.process.workitem; +import java.util.Collection; import java.util.Map; import java.util.function.Function; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; - public interface KogitoWorkItemManager { /** @@ -34,9 +32,15 @@ public interface KogitoWorkItemManager { * @param id the id of the work item that has been completed * @param results the results related to this work item, or null if there are no results */ - void completeWorkItem(String id, - Map results, - Policy... policies); + void completeWorkItem(String id, Map results, Policy... policies); + + /** + * Notifies the work item manager that the work item with the given + * id could not be executed and should be aborted. + * + * @param id the id of the work item that should be aborted + */ + void abortWorkItem(String id, Policy... policies); /** * Updates work item, performing operation indicated by updater @@ -46,18 +50,7 @@ void completeWorkItem(String id, * @param policies optional security information * @return result of the operation performed by updater consumer */ - T updateWorkItem(String id, - Function updater, - Policy... policies); - - /** - * Notifies the work item manager that the work item with the given - * id could not be executed and should be aborted. - * - * @param id the id of the work item that should be aborted - */ - void abortWorkItem(String id, - Policy... policies); + T updateWorkItem(String id, Function updater, Policy... policies); /** * Register the given handler for all work items of the given @@ -66,8 +59,7 @@ void abortWorkItem(String id, * @param workItemName the type of work this work item handler can execute * @param handler the handler for executing work items */ - void registerWorkItemHandler(String workItemName, - KogitoWorkItemHandler handler); + void registerWorkItemHandler(String workItemName, KogitoWorkItemHandler handler); /** * Transition work item with given id into the next life cycle phase. @@ -75,7 +67,20 @@ void registerWorkItemHandler(String workItemName, * @param id work item id to be transitioned * @param transition actual transition to apply to work item */ - default void transitionWorkItem(String id, Transition transition) { + void transitionWorkItem(String id, WorkItemTransition transition); - } + /** + * retrieves the handlers names registered in the work item handler + * + * @return + */ + Collection getHandlerIds(); + + /** + * retrieeves the handle registered by the name + * + * @param name + * @return + */ + KogitoWorkItemHandler getKogitoWorkItemHandler(String name); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/NotAuthorizedException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/NotAuthorizedException.java similarity index 95% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/NotAuthorizedException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/NotAuthorizedException.java index 67f78b07ce9..39ccd8a3c4f 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/NotAuthorizedException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/NotAuthorizedException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; /** * Thrown when there is security violation, usually due to policy enforcement diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Policy.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/Policy.java similarity index 85% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Policy.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/Policy.java index b30d494c93a..085bfbfe6ed 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Policy.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/Policy.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; /** * Top level of a policy that should be applied to work items. @@ -25,12 +25,10 @@ * * @param type of the policy object to be used to react to it. */ -public interface Policy { +public interface Policy { /** - * Actual type of policy data used to enforce this policy - * - * @return policy data + * enforce the policy over this work item handler */ - T value(); + void enforce(KogitoWorkItem workItem); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/WorkItemExecutionException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemExecutionException.java similarity index 97% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/WorkItemExecutionException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemExecutionException.java index 3ed6f70f222..ab65c87b53b 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/WorkItemExecutionException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemExecutionException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; public class WorkItemExecutionException extends RuntimeException { diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/WorkItemHandlerRuntimeException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemHandlerRuntimeException.java similarity index 97% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/WorkItemHandlerRuntimeException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemHandlerRuntimeException.java index a6624a8d669..e36294753d0 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/WorkItemHandlerRuntimeException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemHandlerRuntimeException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.handler; +package org.kie.kogito.internal.process.workitem; import java.util.*; diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/LifeCycle.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemLifeCycle.java similarity index 62% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/LifeCycle.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemLifeCycle.java index 4c5b5102722..d4d2869b98e 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/LifeCycle.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemLifeCycle.java @@ -16,13 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; import java.util.Collection; -import java.util.stream.Stream; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import static java.util.stream.Collectors.toSet; /** * Complete life cycle that can be applied to work items. It defines @@ -30,7 +33,11 @@ * * @param defines the type of data managed through this life cycle */ -public interface LifeCycle { +public interface WorkItemLifeCycle { + + default List phaseByStatus(String phaseStatus) { + return phases().stream().filter(e -> Objects.equals(e.sourceStatus().getName(), phaseStatus)).toList(); + } /** * Returns phase by its id if exists. @@ -38,14 +45,16 @@ public interface LifeCycle { * @param phaseId phase id to be used for look up * @return life cycle phase if exists otherwise null */ - LifeCyclePhase phaseById(String phaseId); + default WorkItemLifeCyclePhase phaseById(String phaseId, String phaseStatus) { + return phases().stream().filter(e -> Objects.equals(e.id(), phaseId) && Objects.equals(e.sourceStatus().getName(), phaseStatus)).findAny().orElse(null); + } /** * Returns all phases associated with this life cycle * * @return list of phases */ - Collection phases(); + Collection phases(); /** * Perform actual transition to the target phase defined via given transition @@ -55,15 +64,7 @@ public interface LifeCycle { * @param transition actual transition * @return returns work item data after the transition */ - T transitionTo(KogitoWorkItem workItem, KogitoWorkItemManager manager, Transition transition); - - /** - * Returns current data set for given work item - * - * @param workItem work item to get the data for - * @return current data set - */ - T data(KogitoWorkItem workItem); + Optional transitionTo(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition); /** * Returns the set of phases the provided phase is able to be transitioned to @@ -71,8 +72,10 @@ public interface LifeCycle { * @param phaseId the phase we want to obtain which phases can be transitioned to * @return stream containing all phases that can be transitioned from the provided phase */ - default Stream allowedPhases(String phaseId) { - LifeCyclePhase activePhase = phaseById(phaseId); - return phases().stream().filter(phase -> phase.canTransition(activePhase)); + default Set allowedPhases(String phaseStatus) { + return this.phaseByStatus(phaseStatus).stream().collect(toSet()); } + + WorkItemTransition newTransition(String transitionId, String phaseStatus, Map map, Policy... policy); + } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/LifeCyclePhase.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemLifeCyclePhase.java similarity index 53% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/LifeCyclePhase.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemLifeCyclePhase.java index ca503fb2ef7..f32daec40fd 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/LifeCyclePhase.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemLifeCyclePhase.java @@ -16,15 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import java.util.Optional; /** * Definition of the life cycle phase that work item can be connected to. * */ -public interface LifeCyclePhase { +public interface WorkItemLifeCyclePhase { /** * Returns unique id of this life cycle phase @@ -34,33 +34,24 @@ public interface LifeCyclePhase { String id(); /** - * Returns status associated with this life cycle phase - * - * @return phase status + * The work item status source from which this transition can start + * + * @return */ - String status(); + WorkItemPhaseState sourceStatus(); /** - * Returns if given state is the terminating phase (final state) for given work item + * the target source in which this transition will end * - * @return true if this is final phase otherwise false + * @return phase status */ - boolean isTerminating(); + WorkItemPhaseState targetStatus(); - /** - * Returns if given life cycle phase can be transitioned to this phase - * - * @param phase phase to be transitioned from - * @return true if phase can be transitioned from to this one otherwise false - */ - boolean canTransition(LifeCyclePhase phase); + boolean isStartingPhase(); /** - * Optional extra work to be applied on work item upon transition to this phase + * execute this life cycle phase * - * @param workitem work item that is being transitioned - * @param transition actual transition */ - default void apply(KogitoWorkItem workitem, Transition transition) { - } + Optional execute(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/WorkItemNotFoundException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemNotFoundException.java similarity index 96% rename from api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/WorkItemNotFoundException.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemNotFoundException.java index d5d3dd94bf2..80dbd305fb5 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/WorkItemNotFoundException.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemNotFoundException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.internal.process.runtime; +package org.kie.kogito.internal.process.workitem; public class WorkItemNotFoundException extends RuntimeException { diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemPhaseState.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemPhaseState.java new file mode 100644 index 00000000000..4c751c9b4cd --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemPhaseState.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.internal.process.workitem; + +import java.util.Optional; + +public final class WorkItemPhaseState { + + private String name; + + private Optional termination; + + private WorkItemPhaseState(String name, WorkItemTerminationType termination) { + this.name = name; + this.termination = Optional.ofNullable(termination); + } + + public static WorkItemPhaseState of(String name) { + return new WorkItemPhaseState(name, null); + } + + public static WorkItemPhaseState of(String name, WorkItemTerminationType termination) { + return new WorkItemPhaseState(name, termination); + } + + public String getName() { + return name; + } + + public Optional getTermination() { + return termination; + } + + public static WorkItemPhaseState initialized() { + return new WorkItemPhaseState(null, null); + } +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTerminationType.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTerminationType.java new file mode 100644 index 00000000000..313cb6760e1 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTerminationType.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.internal.process.workitem; + +public enum WorkItemTerminationType { + COMPLETE, + ABORT +} \ No newline at end of file diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Transition.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTransition.java similarity index 81% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Transition.java rename to api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTransition.java index 49c825328d1..930cc8b7e56 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Transition.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/workitem/WorkItemTransition.java @@ -16,9 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.internal.process.workitem; import java.util.List; +import java.util.Map; +import java.util.Optional; /** * Defines work item life cycle phase transition. @@ -26,14 +28,14 @@ * * @param type of data the transition is carrying */ -public interface Transition { +public interface WorkItemTransition { /** - * Returns target phase where work item should be transitioned + * Returns id phase where work item should be transitioned * * @return target life cycle phase */ - String phase(); + String id(); /** * Optional data to be associated with the transition. @@ -41,12 +43,14 @@ public interface Transition { * * @return data if given otherwise null */ - T data(); + Map data(); /** * Optional list of policies to be enforced during transition * * @return list of policies or an empty list, should never be null */ - List> policies(); + List policies(); + + Optional termination(); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/usertask/event/KogitoUserTaskEventSupport.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/usertask/event/KogitoUserTaskEventSupport.java new file mode 100644 index 00000000000..4adc903a217 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/usertask/event/KogitoUserTaskEventSupport.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.internal.usertask.event; + +import java.util.Map; +import java.util.Set; + +import org.kie.kogito.usertask.UserTaskEventListener; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.Comment; + +public interface KogitoUserTaskEventSupport { + enum AssignmentType { + USER_OWNERS, + USER_GROUPS, + USERS_EXCLUDED, + ADMIN_GROUPS, + ADMIN_USERS + }; + + void fireOneUserTaskStateChange( + UserTaskInstance instance, + String oldPhaseStatus, String newPhaseStatus); + + void fireOnUserTaskNotStartedDeadline( + UserTaskInstance instance, + Map notification); + + void fireOnUserTaskNotCompletedDeadline( + UserTaskInstance instance, + Map notification); + + void fireOnUserTaskAssignmentChange( + UserTaskInstance instance, + AssignmentType assignmentType, + Set oldUsersId, Set newUsersId); + + void fireOnUserTaskInputVariableChange( + UserTaskInstance instance, + String variableName, + Object newValue, Object oldValue); + + void fireOnUserTaskOutputVariableChange( + UserTaskInstance instance, + String variableName, + Object newValue, Object oldValue); + + void fireOnUserTaskAttachmentAdded( + UserTaskInstance instance, + Attachment addedAttachment); + + void fireOnUserTaskAttachmentDeleted( + UserTaskInstance instance, + Attachment deletedAttachment); + + void fireOnUserTaskAttachmentChange( + UserTaskInstance instance, + Attachment oldAttachment, Attachment newAttachment); + + void fireOnUserTaskCommentChange( + UserTaskInstance instance, + Comment oldComment, Comment newComment); + + void fireOnUserTaskCommentDeleted( + UserTaskInstance instance, + Comment deletedComment); + + void fireOnUserTaskCommentAdded( + UserTaskInstance instance, + Comment addedComment); + + void reset(); + + void addEventListener(UserTaskEventListener listener); + + void removeEventListener(UserTaskEventListener listener); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/Process.java b/api/kogito-api/src/main/java/org/kie/kogito/process/Process.java index 2f66cfd2cc4..57dd434542f 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/Process.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/Process.java @@ -19,12 +19,16 @@ package org.kie.kogito.process; import java.util.Collection; +import java.util.Map; import java.util.function.Predicate; import org.kie.kogito.Model; import org.kie.kogito.correlation.CompositeCorrelation; import org.kie.kogito.correlation.CorrelationService; import org.kie.kogito.internal.process.runtime.KogitoNode; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; public interface Process { @@ -59,4 +63,8 @@ public interface Process { void activate(); void deactivate(); + + WorkItemTransition newTransition(WorkItem workItem, String transitionId, Map map, Policy... policy); + + KogitoWorkItemHandler getKogitoWorkItemHandler(String workItemHandlerName); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java index 648204639d6..c9741de02bd 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java @@ -29,11 +29,11 @@ import org.kie.kogito.correlation.Correlation; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.flexible.AdHocFragment; import org.kie.kogito.process.flexible.Milestone; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; public interface ProcessInstance { @@ -157,7 +157,7 @@ public interface ProcessInstance { * @param variables optional variables * @param policies optional list of policies to be enforced */ - void completeWorkItem(String id, Map variables, Policy... policies); + void completeWorkItem(String id, Map variables, Policy... policies); /** * Updates work item according to provided consumer @@ -167,7 +167,7 @@ public interface ProcessInstance { * @param policies optional security information * @return result of the operation performed by the updater */ - R updateWorkItem(String id, Function updater, Policy... policies); + R updateWorkItem(String id, Function updater, Policy... policies); /** * Aborts work item belonging to this process instance @@ -175,7 +175,7 @@ public interface ProcessInstance { * @param id id of the work item to complete * @param policies optional list of policies to be enforced */ - void abortWorkItem(String id, Policy... policies); + void abortWorkItem(String id, Policy... policies); /** * Transition work item belonging to this process instance not another life cycle phase @@ -183,7 +183,7 @@ public interface ProcessInstance { * @param id id of the work item to complete * @param transition target transition including phase, identity and data */ - void transitionWorkItem(String id, Transition transition); + void transitionWorkItem(String id, WorkItemTransition transition); /** * Returns work item identified by given id if found @@ -192,7 +192,7 @@ public interface ProcessInstance { * @param policies optional list of policies to be enforced * @return work item with its parameters if found */ - WorkItem workItem(String workItemId, Policy... policies); + WorkItem workItem(String workItemId, Policy... policies); /** * Return nodes that fulfills a particular filter @@ -208,7 +208,7 @@ public interface ProcessInstance { * @param policies optional list of policies to be enforced * @return list of work items */ - List workItems(Policy... policies); + List workItems(Policy... policies); /** * Returns list of filtered work items @@ -216,7 +216,7 @@ public interface ProcessInstance { * @param p the predicate to be applied to the node holding the work item * @return list of work items */ - List workItems(Predicate p, Policy... policies); + List workItems(Predicate p, Policy... policies); /** * Returns identifier of this process instance diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java index 35ece13d195..d6f6e79ceaa 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java @@ -30,9 +30,10 @@ import org.kie.kogito.Model; import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.correlation.CompositeCorrelation; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.AttachmentInfo; -import org.kie.kogito.process.workitem.Comment; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.AttachmentInfo; +import org.kie.kogito.usertask.model.Comment; public interface ProcessService { @@ -65,6 +66,8 @@ ProcessInstance createProcessInstance(Process process, S , R> Optional findById(Process process, String id); + , R> Optional signalProcessInstance(Process process, String id, Object data, String signalName); + void migrateProcessInstances(Process process, String targetProcessId, String targetProcessVersion, String... id) throws UnsupportedOperationException; long migrateAll(Process process, String targetProcessId, String targetProcessVersion) throws UnsupportedOperationException; @@ -75,31 +78,38 @@ ProcessInstance createProcessInstance(Process process, S , R> Optional updatePartial(Process process, String id, T resource); - Optional> getTasks(Process process, String id, SecurityPolicy policy); + Optional> getWorkItems(Process process, String id, Policy... policy); - Optional signalTask(Process process, String id, String taskNodeName, SecurityPolicy policy); + Optional signalWorkItem(Process process, String id, String taskNodeName, Policy... policy); - Optional saveTask(Process process, + Optional setWorkItemOutput(Process process, String id, String taskId, - SecurityPolicy policy, + Policy policy, MapOutput model, Function, R> mapper); - , R> Optional taskTransition( + , R> Optional transitionWorkItem( Process process, String id, String taskId, String phase, - SecurityPolicy policy, + Policy policy, MapOutput model); - , R> Optional getTask(Process process, + , R> Optional getWorkItem(Process process, String id, String taskId, - SecurityPolicy policy, + Policy policy, Function mapper); + //Schema + Map getWorkItemSchemaAndPhases(Process process, + String id, + String taskId, + String taskName, + Policy policy); + Optional addComment(Process process, String id, String taskId, @@ -160,12 +170,4 @@ Optional> getComments(Process process, String taskId, SecurityPolicy policy); - , R> Optional signalProcessInstance(Process process, String id, Object data, String signalName); - - //Schema - Map getSchemaAndPhases(Process process, - String id, - String taskId, - String taskName, - SecurityPolicy policy); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java b/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java index 11a85db4af8..932b12adf63 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java @@ -30,6 +30,8 @@ default WorkflowElementIdentifier getNodeId() { throw new UnsupportedOperationException(); } + String getWorkItemHandlerName(); + String getNodeInstanceId(); String getName(); @@ -43,4 +45,6 @@ default WorkflowElementIdentifier getNodeId() { Map getParameters(); Map getResults(); + + String getExternalReferenceId(); } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItemHandlerConfig.java b/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItemHandlerConfig.java index 86cfb8271d6..a65ccc5b977 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItemHandlerConfig.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItemHandlerConfig.java @@ -20,7 +20,7 @@ import java.util.Collection; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; public interface WorkItemHandlerConfig { diff --git a/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java b/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java index 089c96d07d8..f9b1a8868f3 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java @@ -29,13 +29,6 @@ import org.kie.api.event.process.ProcessVariableChangedEvent; import org.kie.api.event.process.SLAViolatedEvent; import org.kie.api.event.process.SignalEvent; -import org.kie.api.event.usertask.UserTaskAssignmentEvent; -import org.kie.api.event.usertask.UserTaskAttachmentEvent; -import org.kie.api.event.usertask.UserTaskCommentEvent; -import org.kie.api.event.usertask.UserTaskDeadlineEvent; -import org.kie.api.event.usertask.UserTaskEvent; -import org.kie.api.event.usertask.UserTaskStateEvent; -import org.kie.api.event.usertask.UserTaskVariableEvent; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.ProcessWorkItemTransitionEvent; import org.kie.kogito.uow.UnitOfWorkManager; @@ -54,11 +47,6 @@ private void intercept(ProcessEvent event) { })); } - private void intercept(UserTaskEvent event) { - unitOfWorkManager.currentUnitOfWork().intercept(WorkUnit.create(event, e -> { - })); - } - @Override public void beforeProcessStarted(ProcessStartedEvent event) { } @@ -143,62 +131,6 @@ public void onMigration(ProcessMigrationEvent event) { intercept(event); } - // user tasks - @Override - public void onUserTaskDeadline(UserTaskDeadlineEvent event) { - intercept(event); - } - - @Override - public void onUserTaskState(UserTaskStateEvent event) { - intercept(event); - } - - @Override - public void onUserTaskAssignment(UserTaskAssignmentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskAttachmentAdded(UserTaskAttachmentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskAttachmentChange(UserTaskAttachmentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskAttachmentDeleted(UserTaskAttachmentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskCommentAdded(UserTaskCommentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskCommentChange(UserTaskCommentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskCommentDeleted(UserTaskCommentEvent event) { - intercept(event); - } - - @Override - public void onUserTaskInputVariable(UserTaskVariableEvent event) { - intercept(event); - } - - @Override - public void onUserTaskOutputVariable(UserTaskVariableEvent event) { - intercept(event); - } - @Override public void onError(ErrorEvent event) { intercept(event); diff --git a/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkUserTaskEventListener.java b/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkUserTaskEventListener.java new file mode 100644 index 00000000000..71f932ff470 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkUserTaskEventListener.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.uow.events; + +import org.kie.kogito.uow.UnitOfWorkManager; +import org.kie.kogito.uow.WorkUnit; +import org.kie.kogito.usertask.UserTaskEventListener; +import org.kie.kogito.usertask.events.UserTaskAssignmentEvent; +import org.kie.kogito.usertask.events.UserTaskAttachmentEvent; +import org.kie.kogito.usertask.events.UserTaskCommentEvent; +import org.kie.kogito.usertask.events.UserTaskDeadlineEvent; +import org.kie.kogito.usertask.events.UserTaskEvent; +import org.kie.kogito.usertask.events.UserTaskStateEvent; +import org.kie.kogito.usertask.events.UserTaskVariableEvent; + +public class UnitOfWorkUserTaskEventListener implements UserTaskEventListener { + + UnitOfWorkManager unitOfWorkManager; + + public UnitOfWorkUserTaskEventListener(UnitOfWorkManager unitOfWorkManager) { + this.unitOfWorkManager = unitOfWorkManager; + } + + private void intercept(UserTaskEvent event) { + unitOfWorkManager.currentUnitOfWork().intercept(WorkUnit.create(event, e -> { + })); + } + + public void onUserTaskDeadline(UserTaskDeadlineEvent event) { + intercept(event); + } + + public void onUserTaskState(UserTaskStateEvent event) { + intercept(event); + } + + public void onUserTaskAssignment(UserTaskAssignmentEvent event) { + intercept(event); + } + + public void onUserTaskInputVariable(UserTaskVariableEvent event) { + intercept(event); + } + + public void onUserTaskOutputVariable(UserTaskVariableEvent event) { + intercept(event); + } + + public void onUserTaskAttachmentAdded(UserTaskAttachmentEvent event) { + intercept(event); + } + + public void onUserTaskAttachmentDeleted(UserTaskAttachmentEvent event) { + intercept(event); + } + + public void onUserTaskAttachmentChange(UserTaskAttachmentEvent event) { + intercept(event); + } + + public void onUserTaskCommentChange(UserTaskCommentEvent event) { + intercept(event); + } + + public void onUserTaskCommentAdded(UserTaskCommentEvent event) { + intercept(event); + } + + public void onUserTaskCommentDeleted(UserTaskCommentEvent event) { + intercept(event); + } +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/HumanTaskWorkItem.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java similarity index 73% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/HumanTaskWorkItem.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java index c85f11f3f26..8910256e68d 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/HumanTaskWorkItem.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTask.java @@ -16,18 +16,27 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.usertask; +import java.util.Collection; import java.util.Map; import java.util.Set; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.usertask.model.DeadlineInfo; +import org.kie.kogito.usertask.model.Reassignment; /** - * Dedicated extension to WorkItem to cover needs of human tasks - * + * this is the definition of the user task. Properties are immutable */ -public interface HumanTaskWorkItem extends KogitoWorkItem { +public interface UserTask { + + UserTaskInstance createInstance(); + + UserTaskInstances instances(); + + String id(); + + String name(); /** * Returns name of the task @@ -48,7 +57,7 @@ public interface HumanTaskWorkItem extends KogitoWorkItem { * * @return task priority if present */ - String getTaskPriority(); + Integer getTaskPriority(); /** * Returns reference name of the task @@ -57,13 +66,6 @@ public interface HumanTaskWorkItem extends KogitoWorkItem { */ String getReferenceName(); - /** - * Returns actual owner assigned to the task - * - * @return task actual owner - */ - String getActualOwner(); - /** * Returns potential users that can work on this task * @@ -99,18 +101,12 @@ public interface HumanTaskWorkItem extends KogitoWorkItem { */ Set getExcludedUsers(); - /** - * Returns task attachments - * - * @return A map which key is the attachment id and value the attachment object - */ - Map getAttachments(); + Collection>> getNotStartedDeadlines(); - /** - * Returns task comments - * - * @return A map which key is the comment id and value the comment object - */ - Map getComments(); + Collection>> getNotCompletedDeadlines(); + + Collection> getNotStartedReassignments(); + + Collection> getNotCompletedReassigments(); -} \ No newline at end of file +} diff --git a/api/kogito-api/src/test/java/org/kie/kogito/process/workitem/PoliciesTest.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskConfig.java similarity index 60% rename from api/kogito-api/src/test/java/org/kie/kogito/process/workitem/PoliciesTest.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskConfig.java index 805d5fe317c..ee031f84188 100644 --- a/api/kogito-api/src/test/java/org/kie/kogito/process/workitem/PoliciesTest.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskConfig.java @@ -16,23 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.usertask; -import java.util.Arrays; - -import org.junit.jupiter.api.Test; +import org.kie.kogito.KogitoConfig; import org.kie.kogito.auth.IdentityProvider; +import org.kie.kogito.jobs.JobsService; +import org.kie.kogito.uow.UnitOfWorkManager; +import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle; + +public interface UserTaskConfig extends KogitoConfig { + + UserTaskEventListenerConfig userTaskEventListeners(); + + UserTaskLifeCycle userTaskLifeCycle(); + + UnitOfWorkManager unitOfWorkManager(); -import static org.assertj.core.api.Assertions.assertThat; + JobsService jobsService(); -class PoliciesTest { + IdentityProvider identityProvider(); - @Test - void testPolicies() { - assertThat(Policies.of(null)).isEmpty(); - Policy[] policies = Policies.of("pepe", Arrays.asList("chief", "of", "the", "universe")); - assertThat(policies).hasSize(1); - assertThat(policies[0].value().getName()).isEqualTo("pepe"); - assertThat(policies[0].value().getRoles()).hasSize(4); - } } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListener.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListener.java new file mode 100644 index 00000000000..2eb19f5b174 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListener.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask; + +import org.kie.kogito.usertask.events.UserTaskAssignmentEvent; +import org.kie.kogito.usertask.events.UserTaskAttachmentEvent; +import org.kie.kogito.usertask.events.UserTaskCommentEvent; +import org.kie.kogito.usertask.events.UserTaskDeadlineEvent; +import org.kie.kogito.usertask.events.UserTaskStateEvent; +import org.kie.kogito.usertask.events.UserTaskVariableEvent; + +public interface UserTaskEventListener { + + default void onUserTaskDeadline(UserTaskDeadlineEvent event) { + // nothing + } + + default void onUserTaskState(UserTaskStateEvent event) { + // nothing + } + + default void onUserTaskAssignment(UserTaskAssignmentEvent event) { + // nothing + } + + default void onUserTaskInputVariable(UserTaskVariableEvent event) { + // nothing + } + + default void onUserTaskOutputVariable(UserTaskVariableEvent event) { + // nothing + } + + default void onUserTaskAttachmentAdded(UserTaskAttachmentEvent event) { + // nothing + } + + default void onUserTaskAttachmentDeleted(UserTaskAttachmentEvent event) { + // nothing + } + + default void onUserTaskAttachmentChange(UserTaskAttachmentEvent event) { + // nothing + } + + default void onUserTaskCommentChange(UserTaskCommentEvent event) { + // nothing + } + + default void onUserTaskCommentAdded(UserTaskCommentEvent event) { + // nothing + } + + default void onUserTaskCommentDeleted(UserTaskCommentEvent event) { + // nothing + } +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListenerConfig.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListenerConfig.java new file mode 100644 index 00000000000..1d3f04349b9 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskEventListenerConfig.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask; + +import java.util.List; + +public interface UserTaskEventListenerConfig { + + List listeners(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java new file mode 100644 index 00000000000..9e73f146240 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstance.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.kie.kogito.usertask.lifecycle.UserTaskState; +import org.kie.kogito.usertask.lifecycle.UserTaskTransitionToken; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.Comment; + +public interface UserTaskInstance { + + String getId(); + + UserTask getUserTask(); + + UserTaskState getStatus(); + + boolean hasActualOwner(); + + void setActuaOwner(String string); + + String getActualOwner(); + + UserTaskTransitionToken createTransitionToken(String transitionId, Map data); + + void transition(UserTaskTransitionToken token); + + void complete(); + + void abort(); + + String getExternalReferenceId(); + + String getTaskName(); + + String getTaskDescription(); + + Integer getTaskPriority(); + + Map getMetadata(); + + /** + * Returns potential users that can work on this task + * + * @return potential users + */ + Set getPotentialUsers(); + + /** + * Returns potential groups that can work on this task + * + * @return potential groups + */ + Set getPotentialGroups(); + + /** + * Returns admin users that can administer this task + * + * @return admin users + */ + Set getAdminUsers(); + + /** + * Returns admin groups that can administer this task + * + * @return admin groups + */ + Set getAdminGroups(); + + /** + * Returns excluded users that cannot work on this task + * + * @return excluded users + */ + Set getExcludedUsers(); + + void addAttachment(Attachment attachment); + + void updateAttachment(Attachment newAttachment); + + void removeAttachment(Attachment oldAttachment); + + void addComment(Comment comment); + + void updateComment(Comment newComment); + + void removeComment(Comment comment); + + Collection getComments(); + + Collection getAttachments(); + + Attachment findAttachmentById(String attachmentId); + + Comment findCommentById(String commentId); +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstances.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstances.java new file mode 100644 index 00000000000..57e956bd87f --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTaskInstances.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask; + +import java.util.Optional; +import java.util.function.Function; + +public interface UserTaskInstances { + + Optional findById(String userTaskInstanceId); + + boolean exists(String userTaskInstanceId); + + UserTaskInstance create(UserTaskInstance userTaskInstance); + + UserTaskInstance update(UserTaskInstance userTaskInstance); + + UserTaskInstance remove(String userTaskInstanceId); + + void setReconnectUserTaskInstance(Function reconnectUserTaskInstance); + + void setDisconnectUserTaskInstance(Function disconnectUserTaskInstance); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTasks.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTasks.java new file mode 100644 index 00000000000..3d31047cad2 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/UserTasks.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask; + +import java.util.Collection; + +import org.kie.kogito.KogitoEngine; + +public interface UserTasks extends KogitoEngine { + + UserTask userTaskById(String userTaskId); + + Collection userTaskIds(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAssignmentEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAssignmentEvent.java new file mode 100644 index 00000000000..908c2010ddb --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAssignmentEvent.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.events; + +public interface UserTaskAssignmentEvent extends UserTaskEvent { + + String getAssignmentType(); + + String[] getNewUsersId(); + + String[] getOldUsersId(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAttachmentEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAttachmentEvent.java new file mode 100644 index 00000000000..1ef91af36da --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskAttachmentEvent.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.events; + +import org.kie.kogito.usertask.model.Attachment; + +public interface UserTaskAttachmentEvent extends UserTaskEvent { + + Attachment getOldAttachment(); + + Attachment getNewAttachment(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskCommentEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskCommentEvent.java new file mode 100644 index 00000000000..82b2b52fe8c --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskCommentEvent.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.events; + +import org.kie.kogito.usertask.model.Comment; + +public interface UserTaskCommentEvent extends UserTaskEvent { + + Comment getOldComment(); + + Comment getNewComment(); + +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/SystemOutWorkItemHandler.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskDeadlineEvent.java old mode 100755 new mode 100644 similarity index 52% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/SystemOutWorkItemHandler.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskDeadlineEvent.java index 0b8b569a887..623b1f467dd --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/SystemOutWorkItemHandler.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskDeadlineEvent.java @@ -16,25 +16,32 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.demo; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +package org.kie.kogito.usertask.events; + +import java.util.Map; /** - * + * An event when a dealine for task has expired */ -public class SystemOutWorkItemHandler implements KogitoWorkItemHandler { +public interface UserTaskDeadlineEvent extends UserTaskEvent { - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - System.out.println("Executing work item " + workItem); - manager.completeWorkItem(workItem.getStringId(), null); + enum DeadlineType { + Started, + Completed } - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - System.out.println("Aborting work item " + workItem); - manager.abortWorkItem(workItem.getStringId()); - } + /** + * Returns notification data + * + * @return key-value pair list + */ + Map getNotification(); -} + /** + * Returns dealine type + * + * @return not started or not completed + */ + DeadlineType getType(); +} \ No newline at end of file diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskEvent.java new file mode 100644 index 00000000000..37c7d82f754 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskEvent.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.events; + +import java.util.Date; + +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTaskInstance; + +/** + * A runtime event related to the execution of process instances. + */ +public interface UserTaskEvent { + + UserTask getUserTask(); + + /** + * Retrive the user task instance triggering this event + * + * @return + */ + UserTaskInstance getUserTaskInstance(); + + /** + * Returns exact date when the event was created + * + * @return time when event was created + */ + Date getEventDate(); + + /** + * @return associated identity that performed the event + */ + String getEventUser(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskStateEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskStateEvent.java new file mode 100644 index 00000000000..196b76aafbb --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskStateEvent.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.events; + +public interface UserTaskStateEvent extends UserTaskEvent { + + String getNewStatus(); + + String getOldStatus(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskVariableEvent.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskVariableEvent.java new file mode 100644 index 00000000000..a37ef0011ef --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/events/UserTaskVariableEvent.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.events; + +public interface UserTaskVariableEvent extends UserTaskEvent { + + enum VariableEventType { + INPUT, + OUTPUT + } + + String getVariableName(); + + Object getOldValue(); + + Object getNewValue(); + + VariableEventType getVariableType(); +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java new file mode 100644 index 00000000000..eb8290884a9 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskLifeCycle.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.lifecycle; + +import java.util.Map; +import java.util.Optional; + +import org.kie.kogito.usertask.UserTaskInstance; + +public interface UserTaskLifeCycle { + + Optional transition(UserTaskInstance userTaskInstance, UserTaskTransitionToken transition); + + UserTaskTransitionToken newTransitionToken(String transitionId, UserTaskInstance userTaskInstance, Map data); + + UserTaskTransitionToken newCompleteTransitionToken(UserTaskInstance userTaskInstance, Map emptyMap); + + UserTaskTransitionToken newAbortTransitionToken(UserTaskInstance userTaskInstance, Map emptyMap); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskState.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskState.java new file mode 100644 index 00000000000..71ba89b94d0 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskState.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.lifecycle; + +import java.util.Objects; +import java.util.Optional; + +public class UserTaskState { + + public enum TerminationType { + COMPLETED, + ABORT, + FAILED, + EXITED, + OBSOLETE, + ERROR + } + + private TerminationType terminate; + + private String name; + + public static UserTaskState of(String name) { + return of(name, null); + } + + public static UserTaskState of(String name, TerminationType terminate) { + return new UserTaskState(name, terminate); + } + + public UserTaskState() { + + } + + public TerminationType getTerminate() { + return terminate; + } + + public void setName(String name) { + this.name = name; + } + + public void setTerminate(TerminationType terminate) { + this.terminate = terminate; + } + + private UserTaskState(String name, TerminationType terminate) { + this.name = name; + this.terminate = terminate; + } + + public String getName() { + return name; + } + + public Optional isTerminate() { + return Optional.ofNullable(terminate); + } + + @Override + public int hashCode() { + return Objects.hash(name, terminate); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + UserTaskState other = (UserTaskState) obj; + return Objects.equals(name, other.name) && terminate == other.terminate; + } + + public static UserTaskState initalized() { + return of(null); + } + + @Override + public String toString() { + return "UserTaskState [terminate=" + terminate + ", name=" + name + "]"; + } + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransition.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransition.java new file mode 100644 index 00000000000..7a3328f76a2 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransition.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.lifecycle; + +public interface UserTaskTransition { + + String id(); + + UserTaskState source(); + + UserTaskState target(); + + UserTaskTransitionExecutor executor(); + +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionExecutor.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionExecutor.java new file mode 100644 index 00000000000..6124901d28f --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionExecutor.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.lifecycle; + +import java.util.Optional; + +import org.kie.kogito.usertask.UserTaskInstance; + +public interface UserTaskTransitionExecutor { + + Optional execute(UserTaskInstance transition, UserTaskTransitionToken token); + +} \ No newline at end of file diff --git a/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionToken.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionToken.java new file mode 100644 index 00000000000..db1dd9e8d72 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/lifecycle/UserTaskTransitionToken.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.lifecycle; + +import java.util.Map; + +public interface UserTaskTransitionToken { + + UserTaskTransition transition(); + + Map data(); +} diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Attachment.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Attachment.java similarity index 93% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Attachment.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Attachment.java index 737de03fdfb..04ff75b130a 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Attachment.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Attachment.java @@ -16,10 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.usertask.model; import java.net.URI; +import org.kie.kogito.process.workitem.TaskMetaEntity; + public class Attachment extends TaskMetaEntity { private static final long serialVersionUID = 1L; diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/AttachmentInfo.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/AttachmentInfo.java similarity index 96% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/AttachmentInfo.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/AttachmentInfo.java index 2cbb4693929..c56ed6dd9dd 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/AttachmentInfo.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/AttachmentInfo.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.usertask.model; import java.net.URI; diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Comment.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Comment.java similarity index 86% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Comment.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Comment.java index 237fc0c0cdf..74a801b7112 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Comment.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Comment.java @@ -16,10 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.usertask.model; + +import org.kie.kogito.process.workitem.TaskMetaEntity; public class Comment extends TaskMetaEntity { + private static final long serialVersionUID = -9106249675352498780L; + public Comment(String id, String user) { super(id, user); } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/DeadlineInfo.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/DeadlineInfo.java similarity index 97% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/DeadlineInfo.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/DeadlineInfo.java index 779d9533ba7..32f9251c8c2 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/DeadlineInfo.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/DeadlineInfo.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.humantask; +package org.kie.kogito.usertask.model; import java.io.Serializable; import java.util.Collection; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/Reassignment.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java similarity index 97% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/Reassignment.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java index 3450bf94a33..024532fcf1f 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/Reassignment.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/Reassignment.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.humantask; +package org.kie.kogito.usertask.model; import java.util.Objects; import java.util.Set; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/ScheduleInfo.java b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/ScheduleInfo.java similarity index 98% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/ScheduleInfo.java rename to api/kogito-api/src/main/java/org/kie/kogito/usertask/model/ScheduleInfo.java index 368144bfbd9..579a49a121f 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/ScheduleInfo.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/usertask/model/ScheduleInfo.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.humantask; +package org.kie.kogito.usertask.model; import java.io.Serializable; import java.time.Duration; diff --git a/api/kogito-events-api/src/main/java/org/kie/kogito/event/cloudevents/extension/ProcessMeta.java b/api/kogito-events-api/src/main/java/org/kie/kogito/event/cloudevents/extension/ProcessMeta.java index fad25009d44..ee7075d3370 100644 --- a/api/kogito-events-api/src/main/java/org/kie/kogito/event/cloudevents/extension/ProcessMeta.java +++ b/api/kogito-events-api/src/main/java/org/kie/kogito/event/cloudevents/extension/ProcessMeta.java @@ -22,7 +22,7 @@ import org.kie.kogito.correlation.CompositeCorrelation; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_ABORTED; import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_ACTIVE; diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/BaseEventManager.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/BaseEventManager.java index 60d02a96d46..716de2b72b6 100644 --- a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/BaseEventManager.java +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/BaseEventManager.java @@ -40,7 +40,7 @@ public class BaseEventManager implements EventManager { @Override public EventBatch newBatch() { - return new ProcessInstanceEventBatch(service, addons); + return new DefaultInstanceEventBatch(service, addons); } @Override diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/DefaultInstanceEventBatch.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/DefaultInstanceEventBatch.java new file mode 100644 index 00000000000..c4f6cd76b2f --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/DefaultInstanceEventBatch.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.ServiceLoader; +import java.util.TreeSet; + +import org.kie.kogito.Addons; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.EventBatch; +import org.kie.kogito.event.impl.adapter.DataEventAdapter; +import org.kie.kogito.event.impl.adapter.DataEventAdapter.DataEventAdapterConfig; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DefaultInstanceEventBatch implements EventBatch { + + private static final Logger LOG = LoggerFactory.getLogger(DefaultInstanceEventBatch.class); + + private String service; + private Addons addons; + private Collection> processedEvents; + private List dataEventAdapters; + + public DefaultInstanceEventBatch(String service, Addons addons) { + this.service = service; + this.addons = addons != null ? addons : Addons.EMTPY; + this.processedEvents = new TreeSet<>(new Comparator>() { + @Override + public int compare(DataEvent event1, DataEvent event2) { + return event2 instanceof ProcessInstanceStateDataEvent && + ((ProcessInstanceStateDataEvent) event2).getData().getEventType() == ProcessInstanceStateEventBody.EVENT_TYPE_ENDED + || event1 instanceof ProcessInstanceStateDataEvent && + ((ProcessInstanceStateDataEvent) event1).getData().getEventType() == ProcessInstanceStateEventBody.EVENT_TYPE_STARTED ? -1 : 1; + } + }); + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = this.getClass().getClassLoader(); + } + this.dataEventAdapters = new ArrayList<>(); + ServiceLoader.load(DataEventAdapter.class, cl).forEach(this.dataEventAdapters::add); + this.dataEventAdapters.stream().forEach(a -> a.setup(new DataEventAdapterConfig(this.service, this.addons))); + } + + @Override + public void append(Object event) { + LOG.info("event generated {}", event); + this.dataEventAdapters.stream().filter(a -> a.accept(event)).map(a -> a.adapt(event)).forEach(this.processedEvents::add); + } + + @Override + public Collection> events() { + return processedEvents; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java deleted file mode 100644 index dc10e841e98..00000000000 --- a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.kie.kogito.event.impl; - -import java.time.Instant; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.TreeSet; - -import org.kie.api.event.process.ErrorEvent; -import org.kie.api.event.process.ProcessCompletedEvent; -import org.kie.api.event.process.ProcessEvent; -import org.kie.api.event.process.ProcessMigrationEvent; -import org.kie.api.event.process.ProcessNodeEvent; -import org.kie.api.event.process.ProcessNodeLeftEvent; -import org.kie.api.event.process.ProcessNodeTriggeredEvent; -import org.kie.api.event.process.ProcessStartedEvent; -import org.kie.api.event.process.ProcessVariableChangedEvent; -import org.kie.api.event.process.SLAViolatedEvent; -import org.kie.api.event.usertask.UserTaskAssignmentEvent; -import org.kie.api.event.usertask.UserTaskAttachmentEvent; -import org.kie.api.event.usertask.UserTaskCommentEvent; -import org.kie.api.event.usertask.UserTaskDeadlineEvent; -import org.kie.api.event.usertask.UserTaskStateEvent; -import org.kie.api.event.usertask.UserTaskVariableEvent; -import org.kie.kogito.Addons; -import org.kie.kogito.event.DataEvent; -import org.kie.kogito.event.EventBatch; -import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; -import org.kie.kogito.event.process.ProcessInstanceErrorEventBody; -import org.kie.kogito.event.process.ProcessInstanceEventMetadata; -import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; -import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; -import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; -import org.kie.kogito.event.process.ProcessInstanceSLAEventBody; -import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; -import org.kie.kogito.event.process.ProcessInstanceStateEventBody; -import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; -import org.kie.kogito.event.process.ProcessInstanceVariableEventBody; -import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentEventBody; -import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentEventBody; -import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceCommentEventBody; -import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineEventBody; -import org.kie.kogito.event.usertask.UserTaskInstanceEventMetadata; -import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceStateEventBody; -import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; -import org.kie.kogito.event.usertask.UserTaskInstanceVariableEventBody; -import org.kie.kogito.internal.process.event.KogitoProcessVariableChangedEvent; -import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; -import org.kie.kogito.internal.utils.KogitoTags; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; - -public class ProcessInstanceEventBatch implements EventBatch { - - private String service; - private Addons addons; - Collection> processedEvents; - - public ProcessInstanceEventBatch(String service, Addons addons) { - this.service = service; - this.addons = addons != null ? addons : Addons.EMTPY; - this.processedEvents = new TreeSet<>(new Comparator>() { - @Override - public int compare(DataEvent event1, DataEvent event2) { - return event2 instanceof ProcessInstanceStateDataEvent && - ((ProcessInstanceStateDataEvent) event2).getData().getEventType() == ProcessInstanceStateEventBody.EVENT_TYPE_ENDED - || event1 instanceof ProcessInstanceStateDataEvent && - ((ProcessInstanceStateDataEvent) event1).getData().getEventType() == ProcessInstanceStateEventBody.EVENT_TYPE_STARTED ? -1 : 1; - } - }); - } - - @Override - public void append(Object event) { - if (event instanceof ProcessStartedEvent) { - handleProcessStateEvent((ProcessStartedEvent) event); - } else if (event instanceof ProcessCompletedEvent) { - handleProcessStateEvent((ProcessCompletedEvent) event); - } else if (event instanceof ProcessNodeTriggeredEvent) { - handleProcessNodeEvent((ProcessNodeTriggeredEvent) event); - } else if (event instanceof ProcessNodeLeftEvent) { - handleProcessNodeEvent((ProcessNodeLeftEvent) event); - } else if (event instanceof SLAViolatedEvent) { - handleProcesssNodeEvent((SLAViolatedEvent) event); - } else if (event instanceof ProcessVariableChangedEvent) { - handleProcessVariableEvent((ProcessVariableChangedEvent) event); - } else if (event instanceof ErrorEvent) { - handleErrorEvent((ErrorEvent) event); - } else if (event instanceof UserTaskStateEvent) { - handleUserTaskStateEvent((UserTaskStateEvent) event); - } else if (event instanceof UserTaskDeadlineEvent) { - handleUserTaskDeadlineEvent((UserTaskDeadlineEvent) event); - } else if (event instanceof UserTaskAssignmentEvent) { - handleUserTaskAssignmentEvent((UserTaskAssignmentEvent) event); - } else if (event instanceof UserTaskVariableEvent) { - handleUserTaskVariableEvent((UserTaskVariableEvent) event); - } else if (event instanceof UserTaskAttachmentEvent) { - handleUserTaskAttachmentEvent((UserTaskAttachmentEvent) event); - } else if (event instanceof UserTaskCommentEvent) { - handleUserTaskCommentEvent((UserTaskCommentEvent) event); - } else if (event instanceof ProcessMigrationEvent) { - handleProcessStateEvent((ProcessMigrationEvent) event); - } - } - - @Override - public Collection> events() { - return processedEvents; - } - - private void handleProcessVariableEvent(ProcessVariableChangedEvent event) { - if (event.getTags().contains(KogitoTags.INTERNAL_TAG)) { - return; - } - Map metadata = buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - ProcessInstanceVariableEventBody.Builder builder = ProcessInstanceVariableEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventIdentity()) - .processId(event.getProcessInstance().getProcessId()) - .processVersion(event.getProcessInstance().getProcessVersion()) - .processInstanceId(event.getProcessInstance().getId()) - .variableId(event.getVariableInstanceId()) - .variableName(event.getVariableId()) - .variableValue(event.getNewValue()); - - if (event instanceof KogitoProcessVariableChangedEvent) { - KogitoProcessVariableChangedEvent varEvent = (KogitoProcessVariableChangedEvent) event; - if (varEvent.getNodeInstance() != null && varEvent.getNodeInstance().getNodeInstanceContainer() != null) { - if (varEvent.getNodeInstance().getNodeInstanceContainer() instanceof KogitoNodeInstance) { - builder.nodeContainerDefinitionId(((KogitoNodeInstance) varEvent.getNodeInstance().getNodeInstanceContainer()).getNodeDefinitionId()); - builder.nodeContainerInstanceId(((KogitoNodeInstance) varEvent.getNodeInstance().getNodeInstanceContainer()).getId()); - } - } - } - - ProcessInstanceVariableEventBody body = builder.build(); - ProcessInstanceVariableDataEvent piEvent = - new ProcessInstanceVariableDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventIdentity(), metadata, body); - piEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(piEvent); - } - - private void handleProcesssNodeEvent(SLAViolatedEvent event) { - Map metadata = buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - - ProcessInstanceSLAEventBody.Builder builder = ProcessInstanceSLAEventBody.create() - .eventDate(Date.from(Instant.now())) - .eventUser(event.getEventIdentity()) - .processId(event.getProcessInstance().getProcessId()) - .processVersion(event.getProcessInstance().getProcessVersion()) - .processInstanceId(event.getProcessInstance().getId()); - - if (event.getNodeInstance() instanceof KogitoNodeInstance) { - KogitoNodeInstance ni = (KogitoNodeInstance) event.getNodeInstance(); - builder.nodeDefinitionId(ni.getNode().getUniqueId()) - .nodeInstanceId(ni.getId()) - .nodeName(ni.getNodeName()) - .nodeType(ni.getNode().getClass().getSimpleName()) - .slaDueDate(ni.getSlaDueDate()); - } else { - builder.slaDueDate(pi.getSlaDueDate()); - } - - ProcessInstanceSLAEventBody body = builder.build(); - ProcessInstanceSLADataEvent piEvent = new ProcessInstanceSLADataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventIdentity(), metadata, body); - piEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(piEvent); - } - - private void handleProcessNodeEvent(ProcessNodeLeftEvent event) { - KogitoNodeInstance nodeInstance = (KogitoNodeInstance) event.getNodeInstance(); - int eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_EXIT; - - if (nodeInstance.getCancelType() != null) { - switch (nodeInstance.getCancelType()) { - case ABORTED: - eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_ABORTED; - break; - case SKIPPED: - eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_SKIPPED; - break; - case OBSOLETE: - eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_OBSOLETE; - break; - case ERROR: - eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_ERROR; - } - } - - processedEvents.add(toProcessInstanceNodeEvent(event, eventType)); - } - - private void handleProcessNodeEvent(ProcessNodeTriggeredEvent event) { - processedEvents.add(toProcessInstanceNodeEvent(event, ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER)); - - } - - private ProcessInstanceNodeDataEvent toProcessInstanceNodeEvent(ProcessNodeEvent event, int eventType) { - Map metadata = buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - KogitoNodeInstance nodeInstance = (KogitoNodeInstance) event.getNodeInstance(); - ProcessInstanceNodeEventBody.Builder builder = ProcessInstanceNodeEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventIdentity()) - .eventType(eventType) - .processId(event.getProcessInstance().getProcessId()) - .processVersion(event.getProcessInstance().getProcessVersion()) - .processInstanceId(event.getProcessInstance().getId()) - .nodeName(event.getNodeInstance().getNodeName()) - .nodeType(event.getNodeInstance().getNode().getClass().getSimpleName()) - .nodeInstanceId(event.getNodeInstance().getId()) - .nodeDefinitionId(event.getNodeInstance().getNode().getUniqueId()) - .slaDueDate(nodeInstance.getSlaDueDate()); - - if (eventType == ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER) { - builder.connectionNodeDefinitionId((String) nodeInstance.getMetaData().get("IncomingConnection")); - } else { - builder.connectionNodeDefinitionId((String) nodeInstance.getMetaData().get("OutgoingConnection")); - } - - if (nodeInstance instanceof KogitoWorkItemNodeInstance) { - KogitoWorkItem workItem = ((KogitoWorkItemNodeInstance) nodeInstance).getWorkItem(); - if (workItem != null) { - builder.workItemId(workItem.getStringId()); - } - } - - ProcessInstanceNodeEventBody body = builder.build(); - ProcessInstanceNodeDataEvent piEvent = new ProcessInstanceNodeDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventIdentity(), metadata, body); - piEvent.setKogitoBusinessKey(pi.getBusinessKey()); - return piEvent; - } - - private void handleErrorEvent(ErrorEvent event) { - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - ProcessInstanceErrorEventBody errorBody = ProcessInstanceErrorEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventIdentity()) - .processInstanceId(pi.getId()) - .processId(pi.getProcessId()) - .processVersion(pi.getProcessVersion()) - .nodeDefinitionId(pi.getNodeIdInError()) - .nodeInstanceId(pi.getNodeInstanceIdInError()) - .errorMessage(pi.getErrorMessage()) - .build(); - Map metadata = buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); - ProcessInstanceErrorDataEvent piEvent = - new ProcessInstanceErrorDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventIdentity(), metadata, errorBody); - piEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(piEvent); - } - - private void handleProcessStateEvent(ProcessCompletedEvent event) { - processedEvents.add(toProcessInstanceStateEvent(event, ProcessInstanceStateEventBody.EVENT_TYPE_ENDED)); - } - - private void handleProcessStateEvent(ProcessStartedEvent event) { - processedEvents.add(toProcessInstanceStateEvent(event, ProcessInstanceStateEventBody.EVENT_TYPE_STARTED)); - } - - private void handleProcessStateEvent(ProcessMigrationEvent event) { - processedEvents.add(toProcessInstanceStateEvent(event, ProcessInstanceStateEventBody.EVENT_TYPE_MIGRATED)); - } - - private ProcessInstanceStateDataEvent toProcessInstanceStateEvent(ProcessEvent event, int eventType) { - Map metadata = buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); - - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - - ProcessInstanceStateEventBody.Builder builder = ProcessInstanceStateEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventIdentity()) - .eventType(eventType) - .processId(event.getProcessInstance().getProcessId()) - .processVersion(event.getProcessInstance().getProcessVersion()) - .processInstanceId(event.getProcessInstance().getId()) - .processName(event.getProcessInstance().getProcessName()) - .processVersion(event.getProcessInstance().getProcessVersion()) - .processType(event.getProcessInstance().getProcess().getType()) - .parentInstanceId(pi.getParentProcessInstanceId()) - .rootProcessId(pi.getRootProcessId()) - .rootProcessInstanceId(pi.getRootProcessInstanceId()) - .state(event.getProcessInstance().getState()) - .businessKey(pi.getBusinessKey()) - .slaDueDate(pi.getSlaDueDate()); - - String securityRoles = (String) event.getProcessInstance().getProcess().getMetaData().get("securityRoles"); - if (securityRoles != null) { - builder.roles(securityRoles.split(",")); - } - - ProcessInstanceStateEventBody body = builder.build(); - ProcessInstanceStateDataEvent piEvent = new ProcessInstanceStateDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventIdentity(), metadata, body); - piEvent.setKogitoBusinessKey(pi.getBusinessKey()); - return piEvent; - } - - private Map buildProcessMetadata(KogitoWorkflowProcessInstance pi) { - Map metadata = new HashMap<>(); - metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, pi.getId()); - metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, pi.getProcessVersion()); - metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, pi.getProcessId()); - metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(pi.getState())); - metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, pi.getProcess().getType()); - metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, pi.getParentProcessInstanceId()); - metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, pi.getRootProcessId()); - metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, pi.getRootProcessInstanceId()); - return metadata; - } - - private void handleUserTaskCommentEvent(UserTaskCommentEvent event) { - Map metadata = buildUserTaskMetadata((HumanTaskWorkItem) event.getWorkItem()); - metadata.putAll(buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance())); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - - int eventType = UserTaskInstanceCommentEventBody.EVENT_TYPE_ADDED; - if (event.getOldComment() != null && event.getNewComment() == null) { - eventType = UserTaskInstanceCommentEventBody.EVENT_TYPE_DELETED; - } else if (event.getOldComment() != null && event.getNewComment() != null) { - eventType = UserTaskInstanceCommentEventBody.EVENT_TYPE_CHANGE; - } - - UserTaskInstanceCommentEventBody.Builder builder = UserTaskInstanceCommentEventBody.create() - .eventType(eventType) - .userTaskDefinitionId(event.getUserTaskDefinitionId()) - .userTaskInstanceId(((HumanTaskWorkItem) event.getWorkItem()).getStringId()) - .userTaskName(((HumanTaskWorkItem) event.getWorkItem()).getTaskName()); - - String updatedBy = null; - switch (eventType) { - case UserTaskInstanceCommentEventBody.EVENT_TYPE_ADDED: - case UserTaskInstanceCommentEventBody.EVENT_TYPE_CHANGE: - builder.commentContent(event.getNewComment().getCommentContent()) - .commentId(event.getNewComment().getCommentId()) - .eventDate(event.getNewComment().getUpdatedAt()) - .eventUser(event.getNewComment().getUpdatedBy()); - updatedBy = event.getNewComment().getUpdatedBy(); - break; - case UserTaskInstanceCommentEventBody.EVENT_TYPE_DELETED: - builder.commentId(event.getOldComment().getCommentId()) - .eventDate(event.getOldComment().getUpdatedAt()) - .eventUser(event.getOldComment().getUpdatedBy()); - - updatedBy = event.getOldComment().getUpdatedBy(); - break; - } - - UserTaskInstanceCommentEventBody body = builder.build(); - UserTaskInstanceCommentDataEvent utEvent = new UserTaskInstanceCommentDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), updatedBy, metadata, body); - utEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(utEvent); - - } - - private void handleUserTaskAttachmentEvent(UserTaskAttachmentEvent event) { - Map metadata = buildUserTaskMetadata((HumanTaskWorkItem) event.getWorkItem()); - metadata.putAll(buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance())); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - - int eventType = UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED; - if (event.getOldAttachment() != null && event.getNewAttachment() == null) { - eventType = UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED; - } else if (event.getOldAttachment() != null && event.getNewAttachment() != null) { - eventType = UserTaskInstanceAttachmentEventBody.EVENT_TYPE_CHANGE; - } - - UserTaskInstanceAttachmentEventBody.Builder builder = UserTaskInstanceAttachmentEventBody.create() - .eventType(eventType) - .userTaskDefinitionId(event.getUserTaskDefinitionId()) - .userTaskInstanceId(((HumanTaskWorkItem) event.getWorkItem()).getStringId()) - .userTaskName(((HumanTaskWorkItem) event.getWorkItem()).getTaskName()); - - String updatedBy = null; - switch (eventType) { - case UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED: - case UserTaskInstanceAttachmentEventBody.EVENT_TYPE_CHANGE: - builder.attachmentName(event.getNewAttachment().getAttachmentName()) - .attachmentId(event.getNewAttachment().getAttachmentId()) - .attachmentURI(event.getNewAttachment().getAttachmentURI()) - .eventDate(event.getNewAttachment().getUpdatedAt()) - .eventUser(event.getNewAttachment().getUpdatedBy()); - updatedBy = event.getNewAttachment().getUpdatedBy(); - - break; - case UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED: - builder.attachmentId(event.getOldAttachment().getAttachmentId()) - .eventDate(event.getOldAttachment().getUpdatedAt()) - .eventUser(event.getOldAttachment().getUpdatedBy()); - updatedBy = event.getOldAttachment().getUpdatedBy(); - break; - } - - UserTaskInstanceAttachmentEventBody body = builder.build(); - UserTaskInstanceAttachmentDataEvent utEvent = new UserTaskInstanceAttachmentDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), updatedBy, metadata, body); - utEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(utEvent); - - } - - private void handleUserTaskAssignmentEvent(UserTaskAssignmentEvent event) { - Map metadata = buildUserTaskMetadata((HumanTaskWorkItem) event.getWorkItem()); - metadata.putAll(buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance())); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - UserTaskInstanceAssignmentEventBody.Builder builder = UserTaskInstanceAssignmentEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventUser()) - .userTaskDefinitionId(event.getUserTaskDefinitionId()) - .userTaskInstanceId(((HumanTaskWorkItem) event.getWorkItem()).getStringId()) - .userTaskName(((HumanTaskWorkItem) event.getWorkItem()).getTaskName()) - .assignmentType(event.getAssignmentType()) - .users(event.getNewUsersId()); - - UserTaskInstanceAssignmentEventBody body = builder.build(); - UserTaskInstanceAssignmentDataEvent utEvent = - new UserTaskInstanceAssignmentDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventUser(), metadata, body); - utEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(utEvent); - } - - private void handleUserTaskDeadlineEvent(UserTaskDeadlineEvent event) { - Map metadata = buildUserTaskMetadata((HumanTaskWorkItem) event.getWorkItem()); - metadata.putAll(buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance())); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - UserTaskInstanceDeadlineEventBody.Builder builder = UserTaskInstanceDeadlineEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventUser()) - .userTaskDefinitionId(event.getUserTaskDefinitionId()) - .userTaskInstanceId(((HumanTaskWorkItem) event.getWorkItem()).getStringId()) - .userTaskName(((HumanTaskWorkItem) event.getWorkItem()).getTaskName()) - .notification(event.getNotification()); - - UserTaskInstanceDeadlineEventBody body = builder.build(); - UserTaskInstanceDeadlineDataEvent utEvent = - new UserTaskInstanceDeadlineDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventUser(), metadata, body); - utEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(utEvent); - } - - private void handleUserTaskStateEvent(UserTaskStateEvent event) { - if (event.getNewStatus() == null) { - return; - } - Map metadata = buildUserTaskMetadata((HumanTaskWorkItem) event.getWorkItem()); - metadata.putAll(buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance())); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - UserTaskInstanceStateEventBody.Builder builder = UserTaskInstanceStateEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventUser()) - .userTaskDefinitionId(event.getUserTaskDefinitionId()) - .userTaskInstanceId(((HumanTaskWorkItem) event.getWorkItem()).getStringId()) - .userTaskName(((HumanTaskWorkItem) event.getWorkItem()).getTaskName()) - .userTaskDescription(((HumanTaskWorkItem) event.getWorkItem()).getTaskDescription()) - .userTaskPriority(((HumanTaskWorkItem) event.getWorkItem()).getTaskPriority()) - .userTaskReferenceName(((HumanTaskWorkItem) event.getWorkItem()).getReferenceName()) - .state(event.getNewStatus()) - .actualOwner(((HumanTaskWorkItem) event.getWorkItem()).getActualOwner()) - .eventType(isTransition(event) ? event.getNewStatus() : "Modify") - .processInstanceId(event.getProcessInstance().getId()); - - UserTaskInstanceStateEventBody body = builder.build(); - UserTaskInstanceStateDataEvent utEvent = new UserTaskInstanceStateDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventUser(), metadata, body); - utEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(utEvent); - } - - private boolean isTransition(UserTaskStateEvent event) { - return !Objects.equals(event.getOldStatus(), event.getNewStatus()); - } - - private void handleUserTaskVariableEvent(UserTaskVariableEvent event) { - Map metadata = buildUserTaskMetadata((HumanTaskWorkItem) event.getWorkItem()); - metadata.putAll(buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance())); - KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); - UserTaskInstanceVariableEventBody.Builder builder = UserTaskInstanceVariableEventBody.create() - .eventDate(new Date()) - .eventUser(event.getEventUser()) - .userTaskDefinitionId(event.getUserTaskDefinitionId()) - .userTaskInstanceId(((HumanTaskWorkItem) event.getWorkItem()).getStringId()) - .userTaskName(((HumanTaskWorkItem) event.getWorkItem()).getTaskName()) - .variableId(event.getVariableName()) - .variableName(event.getVariableName()) - .variableValue(event.getNewValue()) - .variableType(event.getVariableType().name()); - - UserTaskInstanceVariableEventBody body = builder.build(); - UserTaskInstanceVariableDataEvent utEvent = - new UserTaskInstanceVariableDataEvent(buildSource(event.getProcessInstance().getProcessId()), addons.toString(), event.getEventUser(), metadata, body); - utEvent.setKogitoBusinessKey(pi.getBusinessKey()); - processedEvents.add(utEvent); - - } - - private Map buildUserTaskMetadata(HumanTaskWorkItem pi) { - Map metadata = new HashMap<>(); - metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_ID_META_DATA, pi.getStringId()); - metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_REFERENCE_ID_META_DATA, pi.getReferenceName()); - metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_STATE_META_DATA, pi.getPhaseStatus()); - - return metadata; - } - - protected String extractRuntimeSource(Map metadata) { - return buildSource(metadata.get(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA)); - } - - private String buildSource(String processId) { - if (processId == null) { - return null; - } else { - return service + "/" + (processId.contains(".") ? processId.substring(processId.lastIndexOf('.') + 1) : processId); - } - } -} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AbstractDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AbstractDataEventAdapter.java new file mode 100644 index 00000000000..72f1bd16701 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AbstractDataEventAdapter.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; + +import org.kie.api.event.process.ProcessEvent; +import org.kie.api.event.process.ProcessNodeEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; +import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemNodeInstance; +import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; + +public abstract class AbstractDataEventAdapter implements DataEventAdapter { + + private DataEventAdapterConfig config; + + private Class type; + + public AbstractDataEventAdapter(Class type) { + this.type = type; + } + + @Override + public void setup(DataEventAdapterConfig config) { + this.config = config; + } + + public DataEventAdapterConfig getConfig() { + return config; + } + + @Override + public Class type() { + return type; + } + + protected ProcessInstanceStateDataEvent adapt(ProcessEvent event, Integer eventType) { + Map metadata = AdapterHelper.buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); + + KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); + + ProcessInstanceStateEventBody.Builder builder = ProcessInstanceStateEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventIdentity()) + .eventType(eventType) + .processId(event.getProcessInstance().getProcessId()) + .processVersion(event.getProcessInstance().getProcessVersion()) + .processInstanceId(event.getProcessInstance().getId()) + .processName(event.getProcessInstance().getProcessName()) + .processVersion(event.getProcessInstance().getProcessVersion()) + .processType(event.getProcessInstance().getProcess().getType()) + .parentInstanceId(pi.getParentProcessInstanceId()) + .rootProcessId(pi.getRootProcessId()) + .rootProcessInstanceId(pi.getRootProcessInstanceId()) + .state(event.getProcessInstance().getState()) + .businessKey(pi.getBusinessKey()) + .slaDueDate(pi.getSlaDueDate()); + + String securityRoles = (String) event.getProcessInstance().getProcess().getMetaData().get("securityRoles"); + if (securityRoles != null) { + builder.roles(securityRoles.split(",")); + } + + ProcessInstanceStateEventBody body = builder.build(); + ProcessInstanceStateDataEvent piEvent = + new ProcessInstanceStateDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getProcessInstance().getProcessId()), getConfig().addons().toString(), + event.getEventIdentity(), metadata, body); + piEvent.setKogitoBusinessKey(pi.getBusinessKey()); + return piEvent; + } + + protected ProcessInstanceNodeDataEvent toProcessInstanceNodeEvent(ProcessNodeEvent event, int eventType) { + Map metadata = AdapterHelper.buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); + KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); + KogitoNodeInstance nodeInstance = (KogitoNodeInstance) event.getNodeInstance(); + ProcessInstanceNodeEventBody.Builder builder = ProcessInstanceNodeEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventIdentity()) + .eventType(eventType) + .processId(event.getProcessInstance().getProcessId()) + .processVersion(event.getProcessInstance().getProcessVersion()) + .processInstanceId(event.getProcessInstance().getId()) + .nodeName(event.getNodeInstance().getNodeName()) + .nodeType(event.getNodeInstance().getNode().getClass().getSimpleName()) + .nodeInstanceId(event.getNodeInstance().getId()) + .nodeDefinitionId(event.getNodeInstance().getNode().getUniqueId()) + .slaDueDate(nodeInstance.getSlaDueDate()); + + if (eventType == ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER) { + builder.connectionNodeDefinitionId((String) nodeInstance.getMetaData().get("IncomingConnection")); + } else { + builder.connectionNodeDefinitionId((String) nodeInstance.getMetaData().get("OutgoingConnection")); + } + + if (nodeInstance instanceof KogitoWorkItemNodeInstance) { + KogitoWorkItem workItem = ((KogitoWorkItemNodeInstance) nodeInstance).getWorkItem(); + if (workItem != null) { + builder.workItemId(workItem.getStringId()); + } + } + + ProcessInstanceNodeEventBody body = builder.build(); + ProcessInstanceNodeDataEvent piEvent = new ProcessInstanceNodeDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getProcessInstance().getProcessId()), + getConfig().addons().toString(), event.getEventIdentity(), metadata, body); + piEvent.setKogitoBusinessKey(pi.getBusinessKey()); + return piEvent; + } +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AdapterHelper.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AdapterHelper.java new file mode 100644 index 00000000000..b2897eec6ec --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/AdapterHelper.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.event.impl.adapter; + +import java.util.HashMap; +import java.util.Map; + +import org.kie.kogito.event.process.ProcessInstanceEventMetadata; +import org.kie.kogito.event.usertask.UserTaskInstanceEventMetadata; +import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.usertask.UserTaskInstance; + +public class AdapterHelper { + + public static Map buildProcessMetadata(KogitoWorkflowProcessInstance pi) { + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, pi.getId()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, pi.getProcessVersion()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, pi.getProcessId()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(pi.getState())); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, pi.getProcess().getType()); + metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, pi.getParentProcessInstanceId()); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, pi.getRootProcessId()); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, pi.getRootProcessInstanceId()); + return metadata; + } + + public static Map buildUserTaskMetadata(UserTaskInstance pi) { + + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, pi.getMetadata().get("ProcessInstanceId")); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, pi.getMetadata().get("ProcessVersion")); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, pi.getMetadata().get("ProcessId")); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(pi.getMetadata().get("ProcessInstanceState"))); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, pi.getMetadata().get("ProcessType")); + metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, pi.getMetadata().get("ParentProcessInstanceId")); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, pi.getMetadata().get("RootProcessId")); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, pi.getMetadata().get("RootProcessInstanceId")); + + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_ID_META_DATA, pi.getExternalReferenceId()); + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_REFERENCE_ID_META_DATA, pi.getUserTask().getReferenceName()); + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_STATE_META_DATA, pi.getStatus().getName()); + + return metadata; + } + + public static String extractRuntimeSource(String service, Map metadata) { + return buildSource(service, metadata.get(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA)); + } + + public static String buildSource(String service, String processId) { + if (processId == null) { + return null; + } else { + return service + "/" + (processId.contains(".") ? processId.substring(processId.lastIndexOf('.') + 1) : processId); + } + } +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/DataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/DataEventAdapter.java new file mode 100644 index 00000000000..535c9cf2e0f --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/DataEventAdapter.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import org.kie.kogito.Addons; +import org.kie.kogito.event.DataEvent; + +public interface DataEventAdapter { + + record DataEventAdapterConfig(String service, Addons addons) { + + } + + void setup(DataEventAdapterConfig config); + + Class type(); + + default boolean accept(Object event) { + return type().isInstance(event); + } + + DataEvent adapt(Object event); +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessCompletedEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessCompletedEventDataEventAdapter.java new file mode 100644 index 00000000000..b10ea69b32f --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessCompletedEventDataEventAdapter.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; + +public class ProcessCompletedEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessCompletedEventDataEventAdapter() { + super(ProcessCompletedEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + return adapt((ProcessCompletedEvent) payload, ProcessInstanceStateEventBody.EVENT_TYPE_ENDED); + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessErrorEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessErrorEventDataEventAdapter.java new file mode 100644 index 00000000000..74025708f37 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessErrorEventDataEventAdapter.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; + +import org.kie.api.event.process.ErrorEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorEventBody; +import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; + +public class ProcessErrorEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessErrorEventDataEventAdapter() { + super(ErrorEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + ErrorEvent event = (ErrorEvent) payload; + KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); + ProcessInstanceErrorEventBody errorBody = ProcessInstanceErrorEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventIdentity()) + .processInstanceId(pi.getId()) + .processId(pi.getProcessId()) + .processVersion(pi.getProcessVersion()) + .nodeDefinitionId(pi.getNodeIdInError()) + .nodeInstanceId(pi.getNodeInstanceIdInError()) + .errorMessage(pi.getErrorMessage()) + .build(); + Map metadata = AdapterHelper.buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); + ProcessInstanceErrorDataEvent piEvent = + new ProcessInstanceErrorDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getProcessInstance().getProcessId()), getConfig().addons().toString(), + event.getEventIdentity(), metadata, errorBody); + piEvent.setKogitoBusinessKey(pi.getBusinessKey()); + return piEvent; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessMigratedEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessMigratedEventDataEventAdapter.java new file mode 100644 index 00000000000..24449d7174c --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessMigratedEventDataEventAdapter.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import org.kie.api.event.process.ProcessMigrationEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; + +public class ProcessMigratedEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessMigratedEventDataEventAdapter() { + super(ProcessMigrationEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + return adapt((ProcessMigrationEvent) payload, ProcessInstanceStateEventBody.EVENT_TYPE_MIGRATED); + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeEnteredEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeEnteredEventDataEventAdapter.java new file mode 100644 index 00000000000..f6a048e27c9 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeEnteredEventDataEventAdapter.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; +import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; + +public class ProcessNodeEnteredEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessNodeEnteredEventDataEventAdapter() { + super(ProcessNodeLeftEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + ProcessNodeLeftEvent event = (ProcessNodeLeftEvent) payload; + KogitoNodeInstance nodeInstance = (KogitoNodeInstance) event.getNodeInstance(); + int eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_EXIT; + + if (nodeInstance.getCancelType() != null) { + switch (nodeInstance.getCancelType()) { + case ABORTED: + eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_ABORTED; + break; + case SKIPPED: + eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_SKIPPED; + break; + case OBSOLETE: + eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_OBSOLETE; + break; + case ERROR: + eventType = ProcessInstanceNodeEventBody.EVENT_TYPE_ERROR; + } + } + + return toProcessInstanceNodeEvent((ProcessNodeLeftEvent) payload, eventType); + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeLeftEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeLeftEventDataEventAdapter.java new file mode 100644 index 00000000000..5ae72fc5b3b --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessNodeLeftEventDataEventAdapter.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import org.kie.api.event.process.ProcessNodeTriggeredEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; + +public class ProcessNodeLeftEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessNodeLeftEventDataEventAdapter() { + super(ProcessNodeTriggeredEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + return toProcessInstanceNodeEvent((ProcessNodeTriggeredEvent) payload, ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER); + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessSLAEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessSLAEventDataEventAdapter.java new file mode 100644 index 00000000000..55e775725fb --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessSLAEventDataEventAdapter.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.time.Instant; +import java.util.Date; +import java.util.Map; + +import org.kie.api.event.process.SLAViolatedEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; +import org.kie.kogito.event.process.ProcessInstanceSLAEventBody; +import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; +import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; + +public class ProcessSLAEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessSLAEventDataEventAdapter() { + super(SLAViolatedEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + SLAViolatedEvent event = (SLAViolatedEvent) payload; + Map metadata = AdapterHelper.buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); + KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); + + ProcessInstanceSLAEventBody.Builder builder = ProcessInstanceSLAEventBody.create() + .eventDate(Date.from(Instant.now())) + .eventUser(event.getEventIdentity()) + .processId(event.getProcessInstance().getProcessId()) + .processVersion(event.getProcessInstance().getProcessVersion()) + .processInstanceId(event.getProcessInstance().getId()); + + if (event.getNodeInstance() instanceof KogitoNodeInstance) { + KogitoNodeInstance ni = (KogitoNodeInstance) event.getNodeInstance(); + builder.nodeDefinitionId(ni.getNode().getUniqueId()) + .nodeInstanceId(ni.getId()) + .nodeName(ni.getNodeName()) + .nodeType(ni.getNode().getClass().getSimpleName()) + .slaDueDate(ni.getSlaDueDate()); + } else { + builder.slaDueDate(pi.getSlaDueDate()); + } + + ProcessInstanceSLAEventBody body = builder.build(); + ProcessInstanceSLADataEvent piEvent = new ProcessInstanceSLADataEvent(AdapterHelper.buildSource(getConfig().service(), event.getProcessInstance().getProcessId()), + getConfig().addons().toString(), event.getEventIdentity(), metadata, body); + piEvent.setKogitoBusinessKey(pi.getBusinessKey()); + return piEvent; + } + +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/DoNothingWorkItemHandler.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessStartedEventDataEventAdapter.java old mode 100755 new mode 100644 similarity index 61% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/DoNothingWorkItemHandler.java rename to api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessStartedEventDataEventAdapter.java index d804487ff32..1070751432b --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/DoNothingWorkItemHandler.java +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessStartedEventDataEventAdapter.java @@ -16,23 +16,21 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.demo; +package org.kie.kogito.event.impl.adapter; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; -/** - * - */ -public class DoNothingWorkItemHandler implements KogitoWorkItemHandler { +public class ProcessStartedEventDataEventAdapter extends AbstractDataEventAdapter { - @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public ProcessStartedEventDataEventAdapter() { + super(ProcessStartedEvent.class); } @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public DataEvent adapt(Object payload) { + return adapt((ProcessStartedEvent) payload, ProcessInstanceStateEventBody.EVENT_TYPE_STARTED); } } diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessVariableEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessVariableEventDataEventAdapter.java new file mode 100644 index 00000000000..f917f002e26 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/ProcessVariableEventDataEventAdapter.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; + +import org.kie.api.event.process.ProcessVariableChangedEvent; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableEventBody; +import org.kie.kogito.internal.process.event.KogitoProcessVariableChangedEvent; +import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; +import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.internal.utils.KogitoTags; + +public class ProcessVariableEventDataEventAdapter extends AbstractDataEventAdapter { + + public ProcessVariableEventDataEventAdapter() { + super(ProcessVariableChangedEvent.class); + } + + @Override + public boolean accept(Object payload) { + return payload instanceof ProcessVariableChangedEvent event && !event.getTags().contains(KogitoTags.INTERNAL_TAG); + } + + @Override + public DataEvent adapt(Object payload) { + ProcessVariableChangedEvent event = (ProcessVariableChangedEvent) payload; + Map metadata = AdapterHelper.buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance()); + KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) event.getProcessInstance(); + ProcessInstanceVariableEventBody.Builder builder = ProcessInstanceVariableEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventIdentity()) + .processId(event.getProcessInstance().getProcessId()) + .processVersion(event.getProcessInstance().getProcessVersion()) + .processInstanceId(event.getProcessInstance().getId()) + .variableId(event.getVariableInstanceId()) + .variableName(event.getVariableId()) + .variableValue(event.getNewValue()); + + if (event instanceof KogitoProcessVariableChangedEvent varEvent) { + if (varEvent.getNodeInstance() != null && varEvent.getNodeInstance().getNodeInstanceContainer() != null) { + if (varEvent.getNodeInstance().getNodeInstanceContainer() instanceof KogitoNodeInstance) { + builder.nodeContainerDefinitionId(((KogitoNodeInstance) varEvent.getNodeInstance().getNodeInstanceContainer()).getNodeDefinitionId()); + builder.nodeContainerInstanceId(((KogitoNodeInstance) varEvent.getNodeInstance().getNodeInstanceContainer()).getId()); + } + } + } + + ProcessInstanceVariableEventBody body = builder.build(); + ProcessInstanceVariableDataEvent piEvent = + new ProcessInstanceVariableDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getProcessInstance().getProcessId()), getConfig().addons().toString(), + event.getEventIdentity(), metadata, body); + piEvent.setKogitoBusinessKey(pi.getBusinessKey()); + return piEvent; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskAssignmentEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskAssignmentEventDataEventAdapter.java new file mode 100644 index 00000000000..215e16ae878 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskAssignmentEventDataEventAdapter.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; + +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentEventBody; +import org.kie.kogito.usertask.events.UserTaskAssignmentEvent; + +public class UserTaskAssignmentEventDataEventAdapter extends AbstractDataEventAdapter { + + public UserTaskAssignmentEventDataEventAdapter() { + super(UserTaskAssignmentEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + UserTaskAssignmentEvent event = (UserTaskAssignmentEvent) payload; + Map metadata = AdapterHelper.buildUserTaskMetadata(event.getUserTaskInstance()); + + UserTaskInstanceAssignmentEventBody.Builder builder = UserTaskInstanceAssignmentEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventUser()) + .userTaskDefinitionId(event.getUserTask().id()) + .userTaskInstanceId(event.getUserTaskInstance().getId()) + .userTaskName(event.getUserTaskInstance().getTaskName()) + .assignmentType(event.getAssignmentType()) + .users(event.getNewUsersId()); + + UserTaskInstanceAssignmentEventBody body = builder.build(); + UserTaskInstanceAssignmentDataEvent utEvent = + new UserTaskInstanceAssignmentDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getUserTaskInstance().getExternalReferenceId()), getConfig().addons().toString(), + event.getEventUser(), metadata, body); + + return utEvent; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskCommentEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskCommentEventDataEventAdapter.java new file mode 100644 index 00000000000..0309c6a1111 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskCommentEventDataEventAdapter.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Map; + +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentEventBody; +import org.kie.kogito.usertask.events.UserTaskCommentEvent; + +public class UserTaskCommentEventDataEventAdapter extends AbstractDataEventAdapter { + + public UserTaskCommentEventDataEventAdapter() { + super(UserTaskCommentEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + UserTaskCommentEvent event = (UserTaskCommentEvent) payload; + Map metadata = AdapterHelper.buildUserTaskMetadata(event.getUserTaskInstance()); + + int eventType = UserTaskInstanceCommentEventBody.EVENT_TYPE_ADDED; + if (event.getOldComment() != null && event.getNewComment() == null) { + eventType = UserTaskInstanceCommentEventBody.EVENT_TYPE_DELETED; + } else if (event.getOldComment() != null && event.getNewComment() != null) { + eventType = UserTaskInstanceCommentEventBody.EVENT_TYPE_CHANGE; + } + + UserTaskInstanceCommentEventBody.Builder builder = UserTaskInstanceCommentEventBody.create() + .eventType(eventType) + .userTaskDefinitionId(event.getUserTask().id()) + .userTaskInstanceId(event.getUserTaskInstance().getId()) + .userTaskName(event.getUserTaskInstance().getTaskName()); + + String updatedBy = null; + switch (eventType) { + case UserTaskInstanceCommentEventBody.EVENT_TYPE_ADDED: + case UserTaskInstanceCommentEventBody.EVENT_TYPE_CHANGE: + builder.commentContent(event.getNewComment().getContent()) + .commentId(event.getNewComment().getId()) + .eventDate(event.getNewComment().getUpdatedAt()) + .eventUser(event.getNewComment().getUpdatedBy()); + updatedBy = event.getNewComment().getUpdatedBy(); + break; + case UserTaskInstanceCommentEventBody.EVENT_TYPE_DELETED: + builder.commentId(event.getOldComment().getId()) + .eventDate(event.getOldComment().getUpdatedAt()) + .eventUser(event.getOldComment().getUpdatedBy()); + + updatedBy = event.getOldComment().getUpdatedBy(); + break; + } + + UserTaskInstanceCommentEventBody body = builder.build(); + UserTaskInstanceCommentDataEvent utEvent = new UserTaskInstanceCommentDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getUserTaskInstance().getExternalReferenceId()), + getConfig().addons().toString(), updatedBy, metadata, body); + + return utEvent; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskDeadlineEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskDeadlineEventDataEventAdapter.java new file mode 100644 index 00000000000..a5b9d539eda --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskDeadlineEventDataEventAdapter.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; + +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineEventBody; +import org.kie.kogito.usertask.events.UserTaskDeadlineEvent; + +public class UserTaskDeadlineEventDataEventAdapter extends AbstractDataEventAdapter { + + public UserTaskDeadlineEventDataEventAdapter() { + super(UserTaskDeadlineEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + UserTaskDeadlineEvent event = (UserTaskDeadlineEvent) payload; + Map metadata = AdapterHelper.buildUserTaskMetadata(event.getUserTaskInstance()); + + UserTaskInstanceDeadlineEventBody.Builder builder = UserTaskInstanceDeadlineEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventUser()) + .userTaskDefinitionId(event.getUserTask().id()) + .userTaskInstanceId(event.getUserTaskInstance().getId()) + .userTaskName(event.getUserTaskInstance().getTaskName()) + .notification(event.getNotification()); + + UserTaskInstanceDeadlineEventBody body = builder.build(); + UserTaskInstanceDeadlineDataEvent utEvent = + new UserTaskInstanceDeadlineDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getUserTaskInstance().getExternalReferenceId()), getConfig().addons().toString(), + event.getEventUser(), metadata, body); + + return utEvent; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskStateEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskStateEventDataEventAdapter.java new file mode 100644 index 00000000000..fe577ac0c29 --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskStateEventDataEventAdapter.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; +import java.util.Objects; + +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateEventBody; +import org.kie.kogito.usertask.events.UserTaskStateEvent; + +public class UserTaskStateEventDataEventAdapter extends AbstractDataEventAdapter { + + public UserTaskStateEventDataEventAdapter() { + super(UserTaskStateEvent.class); + } + + @Override + public boolean accept(Object payload) { + return payload instanceof UserTaskStateEvent event && event.getNewStatus() != null; + } + + @Override + public DataEvent adapt(Object payload) { + UserTaskStateEvent event = (UserTaskStateEvent) payload; + Map metadata = AdapterHelper.buildUserTaskMetadata(event.getUserTaskInstance()); + Integer priority = event.getUserTaskInstance().getTaskPriority(); + String priorityStr = priority != null ? priority.toString() : null; + + UserTaskInstanceStateEventBody.Builder builder = UserTaskInstanceStateEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventUser()) + .userTaskDefinitionId(event.getUserTask().id()) + .userTaskInstanceId(event.getUserTaskInstance().getId()) + .userTaskName(event.getUserTaskInstance().getTaskName()) + .userTaskDescription(event.getUserTaskInstance().getTaskDescription()) + .userTaskPriority(priorityStr) + .userTaskReferenceName(event.getUserTask().getReferenceName()) + .state(event.getNewStatus()) + .actualOwner(event.getUserTaskInstance().getActualOwner()) + .eventType(isTransition(event) ? event.getNewStatus() : "Modify") + .processInstanceId((String) event.getUserTaskInstance().getMetadata().get("ProcessInstanceId")); + + UserTaskInstanceStateEventBody body = builder.build(); + UserTaskInstanceStateDataEvent utEvent = + new UserTaskInstanceStateDataEvent(AdapterHelper.buildSource(getConfig().service(), (String) event.getUserTaskInstance().getMetadata().get("ProcessId")), + getConfig().addons().toString(), + event.getEventUser(), + metadata, body); + + return utEvent; + } + + private boolean isTransition(UserTaskStateEvent event) { + return !Objects.equals(event.getOldStatus(), event.getNewStatus()); + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskVariableEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskVariableEventDataEventAdapter.java new file mode 100644 index 00000000000..5a8d7a7338f --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTaskVariableEventDataEventAdapter.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Date; +import java.util.Map; + +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableEventBody; +import org.kie.kogito.usertask.events.UserTaskVariableEvent; + +public class UserTaskVariableEventDataEventAdapter extends AbstractDataEventAdapter { + + public UserTaskVariableEventDataEventAdapter() { + super(UserTaskVariableEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + UserTaskVariableEvent event = (UserTaskVariableEvent) payload; + Map metadata = AdapterHelper.buildUserTaskMetadata(event.getUserTaskInstance()); + + UserTaskInstanceVariableEventBody.Builder builder = UserTaskInstanceVariableEventBody.create() + .eventDate(new Date()) + .eventUser(event.getEventUser()) + .userTaskDefinitionId(event.getUserTask().id()) + .userTaskInstanceId(event.getUserTaskInstance().getId()) + .userTaskName(event.getUserTaskInstance().getTaskName()) + .variableId(event.getVariableName()) + .variableName(event.getVariableName()) + .variableValue(event.getNewValue()) + .variableType(event.getVariableType().name()); + + UserTaskInstanceVariableEventBody body = builder.build(); + UserTaskInstanceVariableDataEvent utEvent = + new UserTaskInstanceVariableDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getUserTaskInstance().getExternalReferenceId()), getConfig().addons().toString(), + event.getEventUser(), metadata, body); + + return utEvent; + } + +} diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTastAttachmentEventDataEventAdapter.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTastAttachmentEventDataEventAdapter.java new file mode 100644 index 00000000000..f157e41d10b --- /dev/null +++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/adapter/UserTastAttachmentEventDataEventAdapter.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.event.impl.adapter; + +import java.util.Map; + +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentEventBody; +import org.kie.kogito.usertask.events.UserTaskAttachmentEvent; + +public class UserTastAttachmentEventDataEventAdapter extends AbstractDataEventAdapter { + + public UserTastAttachmentEventDataEventAdapter() { + super(UserTaskAttachmentEvent.class); + } + + @Override + public DataEvent adapt(Object payload) { + UserTaskAttachmentEvent event = (UserTaskAttachmentEvent) payload; + Map metadata = AdapterHelper.buildUserTaskMetadata(event.getUserTaskInstance()); + + int eventType = UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED; + if (event.getOldAttachment() != null && event.getNewAttachment() == null) { + eventType = UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED; + } else if (event.getOldAttachment() != null && event.getNewAttachment() != null) { + eventType = UserTaskInstanceAttachmentEventBody.EVENT_TYPE_CHANGE; + } + + UserTaskInstanceAttachmentEventBody.Builder builder = UserTaskInstanceAttachmentEventBody.create() + .eventType(eventType) + .userTaskDefinitionId(event.getUserTask().id()) + .userTaskInstanceId(event.getUserTaskInstance().getId()) + .userTaskName(event.getUserTaskInstance().getTaskName()); + + String updatedBy = null; + switch (eventType) { + case UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED: + case UserTaskInstanceAttachmentEventBody.EVENT_TYPE_CHANGE: + builder.attachmentName(event.getNewAttachment().getName()) + .attachmentId(event.getNewAttachment().getId()) + .attachmentURI(event.getNewAttachment().getContent()) + .eventDate(event.getNewAttachment().getUpdatedAt()) + .eventUser(event.getNewAttachment().getUpdatedBy()); + updatedBy = event.getNewAttachment().getUpdatedBy(); + + break; + case UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED: + builder.attachmentId(event.getOldAttachment().getId()) + .eventDate(event.getOldAttachment().getUpdatedAt()) + .eventUser(event.getOldAttachment().getUpdatedBy()); + updatedBy = event.getOldAttachment().getUpdatedBy(); + break; + } + + UserTaskInstanceAttachmentEventBody body = builder.build(); + UserTaskInstanceAttachmentDataEvent utEvent = new UserTaskInstanceAttachmentDataEvent(AdapterHelper.buildSource(getConfig().service(), event.getUserTaskInstance().getExternalReferenceId()), + getConfig().addons().toString(), updatedBy, metadata, body); + + return utEvent; + } + +} diff --git a/api/kogito-events-core/src/main/resources/META-INF/services/org.kie.kogito.event.impl.adapter.DataEventAdapter b/api/kogito-events-core/src/main/resources/META-INF/services/org.kie.kogito.event.impl.adapter.DataEventAdapter new file mode 100644 index 00000000000..644f544a1bc --- /dev/null +++ b/api/kogito-events-core/src/main/resources/META-INF/services/org.kie.kogito.event.impl.adapter.DataEventAdapter @@ -0,0 +1,14 @@ +org.kie.kogito.event.impl.adapter.ProcessCompletedEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessErrorEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessMigratedEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessNodeEnteredEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessNodeLeftEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessSLAEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessStartedEventDataEventAdapter +org.kie.kogito.event.impl.adapter.ProcessVariableEventDataEventAdapter +org.kie.kogito.event.impl.adapter.UserTaskAssignmentEventDataEventAdapter +org.kie.kogito.event.impl.adapter.UserTaskCommentEventDataEventAdapter +org.kie.kogito.event.impl.adapter.UserTaskDeadlineEventDataEventAdapter +org.kie.kogito.event.impl.adapter.UserTastAttachmentEventDataEventAdapter +org.kie.kogito.event.impl.adapter.UserTaskVariableEventDataEventAdapter +org.kie.kogito.event.impl.adapter.UserTaskStateEventDataEventAdapter \ No newline at end of file diff --git a/api/kogito-events-core/src/test/java/org/kie/kogito/event/impl/ProcessInstanceEventBatchTest.java b/api/kogito-events-core/src/test/java/org/kie/kogito/event/impl/ProcessInstanceEventBatchTest.java index b4326cc2283..1632fecf883 100644 --- a/api/kogito-events-core/src/test/java/org/kie/kogito/event/impl/ProcessInstanceEventBatchTest.java +++ b/api/kogito-events-core/src/test/java/org/kie/kogito/event/impl/ProcessInstanceEventBatchTest.java @@ -29,6 +29,7 @@ import org.kie.api.event.process.ProcessVariableChangedEvent; import org.kie.api.runtime.process.NodeInstance; import org.kie.api.runtime.process.ProcessInstance; +import org.kie.kogito.event.impl.adapter.AdapterHelper; import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; @@ -48,29 +49,24 @@ public class ProcessInstanceEventBatchTest { @Test public void testNoServiceDefined() { - ProcessInstanceEventBatch batch = new ProcessInstanceEventBatch("", null); - - assertThat(batch.extractRuntimeSource(singletonMap(PROCESS_ID_META_DATA, "travels"))).isEqualTo("/travels"); - assertThat(batch.extractRuntimeSource(singletonMap(PROCESS_ID_META_DATA, "demo.orders"))).isEqualTo("/orders"); + assertThat(AdapterHelper.extractRuntimeSource("", singletonMap(PROCESS_ID_META_DATA, "travels"))).isEqualTo("/travels"); + assertThat(AdapterHelper.extractRuntimeSource("", singletonMap(PROCESS_ID_META_DATA, "demo.orders"))).isEqualTo("/orders"); } @Test public void testNoProcessIdDefined() { - ProcessInstanceEventBatch batch = new ProcessInstanceEventBatch("http://localhost:8080", null); - assertThat(batch.extractRuntimeSource(emptyMap())).isNull(); + assertThat(AdapterHelper.extractRuntimeSource("http://localhost:8080", emptyMap())).isNull(); } @Test public void testServiceDefined() { - ProcessInstanceEventBatch batch = new ProcessInstanceEventBatch("http://localhost:8080", null); - - assertThat(batch.extractRuntimeSource(singletonMap(PROCESS_ID_META_DATA, "travels"))).isEqualTo("http://localhost:8080/travels"); - assertThat(batch.extractRuntimeSource(singletonMap(PROCESS_ID_META_DATA, "demo.orders"))).isEqualTo("http://localhost:8080/orders"); + assertThat(AdapterHelper.extractRuntimeSource("http://localhost:8080", singletonMap(PROCESS_ID_META_DATA, "travels"))).isEqualTo("http://localhost:8080/travels"); + assertThat(AdapterHelper.extractRuntimeSource("http://localhost:8080", singletonMap(PROCESS_ID_META_DATA, "demo.orders"))).isEqualTo("http://localhost:8080/orders"); } @Test public void testEventSorting() { - ProcessInstanceEventBatch batch = new ProcessInstanceEventBatch("", null); + DefaultInstanceEventBatch batch = new DefaultInstanceEventBatch("", null); KogitoWorkflowProcess process = Mockito.mock(KogitoWorkflowProcess.class); KogitoWorkflowProcessInstance processInstance = Mockito.mock(KogitoWorkflowProcessInstance.class); KogitoNodeInstance nodeInstance = Mockito.mock(KogitoNodeInstance.class); @@ -87,7 +83,7 @@ public void testEventSorting() { batch.append(mockEvent(ProcessCompletedEvent.class, processInstance)); batch.append(mockEvent(ProcessNodeTriggeredEvent.class, processInstance, nodeInstance)); batch.append(mockEvent(ProcessNodeLeftEvent.class, processInstance, nodeInstance)); - assertThat(batch.processedEvents).hasExactlyElementsOfTypes(ProcessInstanceStateDataEvent.class, ProcessInstanceVariableDataEvent.class, ProcessInstanceNodeDataEvent.class, + assertThat(batch.events()).hasExactlyElementsOfTypes(ProcessInstanceStateDataEvent.class, ProcessInstanceVariableDataEvent.class, ProcessInstanceNodeDataEvent.class, ProcessInstanceNodeDataEvent.class, ProcessInstanceNodeDataEvent.class, ProcessInstanceNodeDataEvent.class, ProcessInstanceErrorDataEvent.class, ProcessInstanceNodeDataEvent.class, ProcessInstanceNodeDataEvent.class, ProcessInstanceStateDataEvent.class); diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ReceiveTaskHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ReceiveTaskHandler.java deleted file mode 100755 index 2a1d17371da..00000000000 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ReceiveTaskHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.bpmn2.handler; - -import java.util.HashMap; -import java.util.Map; - -import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; - -public class ReceiveTaskHandler implements KogitoWorkItemHandler { - - // TODO: use correlation instead of message id - private Map waiting = new HashMap<>(); - private KogitoProcessRuntime kruntime; - - public ReceiveTaskHandler(KogitoProcessRuntime kruntime) { - this.kruntime = kruntime; - } - - public void setKnowledgeRuntime(KogitoProcessRuntime kruntime) { - this.kruntime = kruntime; - } - - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - String messageId = (String) workItem.getParameter("MessageId"); - waiting.put(messageId, workItem.getStringId()); - } - - public void messageReceived(String messageId, Object message) { - String workItemId = waiting.get(messageId); - if (workItemId == null) { - return; - } - Map results = new HashMap<>(); - results.put("Message", message); - kruntime.getKogitoWorkItemManager().completeWorkItem(workItemId, results); - } - - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - String messageId = (String) workItem.getParameter("MessageId"); - waiting.remove(messageId); - } - -} diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/TaskHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/TaskHandler.java index 017e3e80125..114a28051bc 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/TaskHandler.java +++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/TaskHandler.java @@ -70,6 +70,7 @@ protected Node handleNode(final Node node, final Element element, final String u } // this is a hack as most of the examples in kogito depends on this evaluation + work.setParameter(Work.PARAMETER_UNIQUE_TASK_ID, workItemNode.getUniqueId()); work.setParameter("NodeName", workItemNode.getName()); setParameter(work, "TaskName", workItemNode.getIoSpecification().getDataInputAssociation()); workItemNode.setMetaData("DataInputs", new HashMap()); diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/UserTaskHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/UserTaskHandler.java index e59037960fc..f325438516a 100644 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/UserTaskHandler.java +++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/UserTaskHandler.java @@ -43,7 +43,20 @@ public Class generateNodeFor() { } private static final Set taskParameters = Set.of( - "NotStartedNotify", "NotCompletedNotify", "NotCompletedReassign", "NotStartedReassign", "Description", "Comment", "ActorId", "GroupId", "Priority", "Skippable", "Content"); + "NotStartedNotify", + "NotCompletedNotify", + "NotCompletedReassign", + "NotStartedReassign", + "Description", + "Comment", + "ActorId", + "GroupId", + "Priority", + "Skippable", + "Content", + "ExcludedOwnerId", + "BusinessAdministratorId", + "BusinessAdministratorGroupId"); @Override protected Node handleNode(final Node node, final Element element, final String uri, diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentBuilder.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentBuilder.java index 364f8899cf5..2b16db54e89 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentBuilder.java +++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentBuilder.java @@ -23,6 +23,7 @@ import org.drools.compiler.rule.builder.PackageBuildContext; import org.jbpm.process.builder.AssignmentBuilder; import org.jbpm.workflow.core.impl.DataDefinition; +import org.jbpm.workflow.core.impl.XPATHAssignmentAction; import org.jbpm.workflow.core.node.Assignment; public class XPATHAssignmentBuilder implements AssignmentBuilder { diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java index e6a29b85c11..df188e2b2e8 100644 --- a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java +++ b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java @@ -32,6 +32,7 @@ import org.kie.kogito.correlation.CompositeCorrelation; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.WorkItemHandlerConfig; import org.kie.kogito.process.impl.AbstractProcess; import org.kie.kogito.process.impl.DefaultProcessEventListenerConfig; import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; @@ -122,8 +123,11 @@ public static void overrideCompiler(BpmnProcessCompiler compiler) { } public static List from(Resource... resource) { - return from(new StaticProcessConfig(new DefaultWorkItemHandlerConfig(), new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())), - resource); + return from(new DefaultWorkItemHandlerConfig(), resource); + } + + public static List from(WorkItemHandlerConfig config, Resource... resource) { + return from(new StaticProcessConfig(config, new DefaultProcessEventListenerConfig(), new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())), resource); } public static List from(ProcessConfig config, Resource... resources) { diff --git a/jbpm/jbpm-deps-groups/jbpm-deps-group-bpmn2-compiler/pom.xml b/jbpm/jbpm-deps-groups/jbpm-deps-group-bpmn2-compiler/pom.xml index 3b857f3744c..12a419d59e8 100644 --- a/jbpm/jbpm-deps-groups/jbpm-deps-group-bpmn2-compiler/pom.xml +++ b/jbpm/jbpm-deps-groups/jbpm-deps-group-bpmn2-compiler/pom.xml @@ -37,6 +37,10 @@ org.kie.kogito process-workitems + + org.kie.kogito + jbpm-usertask + diff --git a/jbpm/jbpm-deps-groups/jbpm-deps-group-compiler/pom.xml b/jbpm/jbpm-deps-groups/jbpm-deps-group-compiler/pom.xml index e0dc237f2ae..549fe524212 100644 --- a/jbpm/jbpm-deps-groups/jbpm-deps-group-compiler/pom.xml +++ b/jbpm/jbpm-deps-groups/jbpm-deps-group-compiler/pom.xml @@ -32,6 +32,10 @@ org.kie.kogito process-workitems + + org.kie.kogito + jbpm-usertask + diff --git a/jbpm/jbpm-deps-groups/jbpm-deps-group-engine/pom.xml b/jbpm/jbpm-deps-groups/jbpm-deps-group-engine/pom.xml index a369f256471..95c51d1b808 100644 --- a/jbpm/jbpm-deps-groups/jbpm-deps-group-engine/pom.xml +++ b/jbpm/jbpm-deps-groups/jbpm-deps-group-engine/pom.xml @@ -33,6 +33,11 @@ org.kie.kogito process-workitems + + + org.kie.kogito + jbpm-usertask + diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/AbstractServiceTaskDescriptor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/AbstractServiceTaskDescriptor.java index 83149409b52..6bdb718bf58 100644 --- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/AbstractServiceTaskDescriptor.java +++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/AbstractServiceTaskDescriptor.java @@ -18,16 +18,21 @@ */ package org.jbpm.compiler.canonical.descriptors; +import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Optional; import org.jbpm.compiler.canonical.NodeValidator; import org.jbpm.workflow.core.impl.DataAssociation; import org.jbpm.workflow.core.node.WorkItemNode; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.Modifier; @@ -58,6 +63,8 @@ import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.UnionType; +import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; + public abstract class AbstractServiceTaskDescriptor implements TaskDescriptor { static final String PARAM_INTERFACE = "Interface"; @@ -87,22 +94,21 @@ protected Expression handleServiceCallResult(final BlockStmt executeWorkItemBody protected abstract Collection> getCompleteWorkItemExceptionTypes(); - private Statement tryStmt(Expression expr, Collection> exceptions) { - return exceptions.isEmpty() ? new ExpressionStmt(expr) - : new TryStmt( - new BlockStmt().addStatement(expr), - NodeList - .nodeList( - new CatchClause( - new Parameter(processException(exceptions), new SimpleName(EXCEPTION_NAME)), - new BlockStmt() - .addStatement( - new ThrowStmt( - new ObjectCreationExpr() - .setType(WorkItemExecutionException.class) - .addArgument(new StringLiteralExpr("500")) - .addArgument(new NameExpr(EXCEPTION_NAME)))))), - null); + private BlockStmt tryStmt(BlockStmt blockStmt, Collection> exceptions) { + if (exceptions.isEmpty()) { + return blockStmt; + } else { + Expression newExceptionExpression = new ObjectCreationExpr() + .setType(WorkItemExecutionException.class) + .addArgument(new StringLiteralExpr("500")) + .addArgument(new NameExpr(EXCEPTION_NAME)); + + BlockStmt throwBlockStmt = new BlockStmt().addStatement(new ThrowStmt(newExceptionExpression)); + CatchClause catchClause = new CatchClause(new Parameter(processException(exceptions), new SimpleName(EXCEPTION_NAME)), throwBlockStmt); + NodeList clauses = NodeList.nodeList(catchClause); + return new BlockStmt().addStatement(new TryStmt().setTryBlock(blockStmt).setCatchClauses(clauses)); + } + } private Type processException(Collection> exceptions) { @@ -118,46 +124,15 @@ protected boolean isEmptyResult() { return false; } - protected MethodCallExpr completeWorkItem(BlockStmt executeWorkItemBody, MethodCallExpr callService, Collection> exceptions) { - Expression results; - - List outAssociations = workItemNode.getOutAssociations(); - if (outAssociations.isEmpty() || isEmptyResult()) { - executeWorkItemBody.addStatement(tryStmt(callService, exceptions)); - results = new MethodCallExpr(new NameExpr("java.util.Collections"), "emptyMap"); - } else { - VariableDeclarationExpr resultField = new VariableDeclarationExpr() - .addVariable(new VariableDeclarator( - new ClassOrInterfaceType(null, Object.class.getCanonicalName()), - RESULT_NAME)); - executeWorkItemBody.addStatement(resultField); - executeWorkItemBody - .addStatement( - tryStmt( - new AssignExpr( - new NameExpr(RESULT_NAME), - callService, - AssignExpr.Operator.ASSIGN), - exceptions)); - results = new MethodCallExpr(new NameExpr("java.util.Collections"), "singletonMap") - .addArgument(new StringLiteralExpr(outAssociations.get(0).getSources().get(0).getLabel())) - .addArgument(new NameExpr(RESULT_NAME)); - } - - return new MethodCallExpr(new NameExpr("workItemManager"), "completeWorkItem") - .addArgument(new MethodCallExpr(new NameExpr("workItem"), "getStringId")) - .addArgument(results); - } - protected final ClassOrInterfaceDeclaration classDeclaration() { String unqualifiedName = StaticJavaParser.parseName(getName()).removeQualifier().asString(); ClassOrInterfaceDeclaration cls = new ClassOrInterfaceDeclaration() .setName(unqualifiedName) .setModifiers(Modifier.Keyword.PUBLIC) - .addImplementedType(KogitoWorkItemHandler.class.getCanonicalName()); + .addExtendedType(DefaultKogitoWorkItemHandler.class.getCanonicalName()); ClassOrInterfaceType serviceType = new ClassOrInterfaceType(null, interfaceName); - final String serviceName = "service"; + String serviceName = "service"; FieldDeclaration serviceField = new FieldDeclaration() .addVariable(new VariableDeclarator(serviceType, serviceName)); cls.addMember(serviceField); @@ -179,34 +154,53 @@ protected final ClassOrInterfaceDeclaration classDeclaration() { new NameExpr(serviceName), AssignExpr.Operator.ASSIGN))); + Type workItemTransitionType = parseClassOrInterfaceType(WorkItemTransition.class.getName()); + ClassOrInterfaceType optionalClass = parseClassOrInterfaceType(Optional.class.getName()).setTypeArguments(workItemTransitionType); + // executeWorkItem method BlockStmt executeWorkItemBody = new BlockStmt(); - MethodDeclaration executeWorkItem = new MethodDeclaration() - .setModifiers(Modifier.Keyword.PUBLIC) - .setType(void.class) - .setName("executeWorkItem") - .setBody(executeWorkItemBody) - .addParameter(KogitoWorkItem.class.getCanonicalName(), "workItem") - .addParameter(KogitoWorkItemManager.class.getCanonicalName(), "workItemManager"); - MethodCallExpr callService = new MethodCallExpr(new NameExpr("service"), operationName); this.handleParametersForServiceCall(executeWorkItemBody, callService); - MethodCallExpr completeWorkItem = completeWorkItem( - executeWorkItemBody, - callService, - getCompleteWorkItemExceptionTypes()); + // execute work item handler + getWorkItemOutput(callService).forEach(executeWorkItemBody::addStatement); + + Expression completeExpression = new ThisExpr(); + completeExpression = new FieldAccessExpr(completeExpression, "workItemLifeCycle"); + NodeList arguments = new NodeList<>(); + arguments.add(new StringLiteralExpr("complete")); + arguments.add(new MethodCallExpr(new NameExpr("workItem"), "getPhaseStatus")); + arguments.add(new NameExpr(RESULT_NAME)); + + completeExpression = new MethodCallExpr(completeExpression, "newTransition", arguments); + Statement completeWorkItem = new ReturnStmt(new MethodCallExpr(new NameExpr(Optional.class.getName()), "of", NodeList.nodeList(completeExpression))); executeWorkItemBody.addStatement(completeWorkItem); + executeWorkItemBody = tryStmt(executeWorkItemBody, getCompleteWorkItemExceptionTypes()); + + MethodDeclaration executeWorkItem = new MethodDeclaration() + .setModifiers(Modifier.Keyword.PUBLIC) + .setType(optionalClass) + .setName("activateWorkItemHandler") + .setBody(executeWorkItemBody) + .addParameter(KogitoWorkItemManager.class.getCanonicalName(), "workItemManager") + .addParameter(KogitoWorkItemHandler.class.getCanonicalName(), "workItemHandler") + .addParameter(KogitoWorkItem.class.getCanonicalName(), "workItem") + .addParameter(WorkItemTransition.class.getCanonicalName(), "transition"); + // abortWorkItem method BlockStmt abortWorkItemBody = new BlockStmt(); MethodDeclaration abortWorkItem = new MethodDeclaration() .setModifiers(Modifier.Keyword.PUBLIC) - .setType(void.class) - .setName("abortWorkItem") + .setType(optionalClass) + .setName("abortWorkItemHandler") .setBody(abortWorkItemBody) + .addParameter(KogitoWorkItemManager.class.getCanonicalName(), "workItemManager") + .addParameter(KogitoWorkItemHandler.class.getCanonicalName(), "workItemHandler") .addParameter(KogitoWorkItem.class.getCanonicalName(), "workItem") - .addParameter(KogitoWorkItemManager.class.getCanonicalName(), "workItemManager"); + .addParameter(WorkItemTransition.class.getCanonicalName(), "transition"); + + abortWorkItemBody.addStatement(new ReturnStmt(new MethodCallExpr(new NameExpr(Optional.class.getName()), "empty"))); // getName method MethodDeclaration getName = new MethodDeclaration() @@ -220,4 +214,31 @@ protected final ClassOrInterfaceDeclaration classDeclaration() { return cls; } + + protected List getWorkItemOutput(Expression callServiceExpression) { + List statements = new ArrayList<>(); + + ClassOrInterfaceType stringType = new ClassOrInterfaceType(null, String.class.getCanonicalName()); + ClassOrInterfaceType objectType = new ClassOrInterfaceType(null, Object.class.getCanonicalName()); + ClassOrInterfaceType map = new ClassOrInterfaceType(null, Map.class.getCanonicalName()).setTypeArguments(stringType, objectType); + VariableDeclarationExpr resultField = new VariableDeclarationExpr(new VariableDeclarator(map, RESULT_NAME)); + statements.add(new ExpressionStmt(resultField)); + + Expression resultExpression = null; + List outAssociations = workItemNode.getOutAssociations(); + if (outAssociations.isEmpty() || isEmptyResult()) { + statements.add(new ExpressionStmt(callServiceExpression)); + resultExpression = new MethodCallExpr(new NameExpr("java.util.Collections"), "emptyMap"); + resultExpression = new AssignExpr(new NameExpr(RESULT_NAME), resultExpression, AssignExpr.Operator.ASSIGN); + statements.add(new ExpressionStmt(resultExpression)); + } else { + resultExpression = new MethodCallExpr(new NameExpr("java.util.Collections"), "singletonMap") + .addArgument(new StringLiteralExpr(outAssociations.get(0).getSources().get(0).getLabel())) + .addArgument(callServiceExpression); + resultExpression = new AssignExpr(new NameExpr(RESULT_NAME), resultExpression, AssignExpr.Operator.ASSIGN); + statements.add(new ExpressionStmt(resultExpression)); + } + + return statements; + } } diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java index 26a475e8f79..2ea4166ba06 100644 --- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java +++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java @@ -32,7 +32,7 @@ import org.jbpm.util.ContextFactory; import org.jbpm.workflow.core.node.WorkItemNode; import org.kie.kogito.internal.process.runtime.KogitoProcessContext; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.expr.CastExpr; diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/NodeLeftCountDownProcessEventListener.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/NodeLeftCountDownProcessEventListener.java index 92e5fb4a535..be977249d57 100644 --- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/NodeLeftCountDownProcessEventListener.java +++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/NodeLeftCountDownProcessEventListener.java @@ -19,9 +19,12 @@ package org.jbpm.test.util; import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.api.event.process.ProcessNodeTriggeredEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NodeLeftCountDownProcessEventListener extends DefaultCountDownProcessEventListener { - + private static final Logger logger = LoggerFactory.getLogger(NodeLeftCountDownProcessEventListener.class); private String nodeName; public NodeLeftCountDownProcessEventListener() { @@ -33,8 +36,14 @@ public NodeLeftCountDownProcessEventListener(String nodeName, int threads) { this.nodeName = nodeName; } + @Override + public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { + logger.info("before node left {}", event); + } + @Override public void afterNodeLeft(ProcessNodeLeftEvent event) { + logger.info("after node left {}", event); if (nodeName.equals(event.getNodeInstance().getNodeName())) { countDown(); } diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/ProcessCompletedCountDownProcessEventListener.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/ProcessCompletedCountDownProcessEventListener.java index 64b78629531..05096442707 100644 --- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/ProcessCompletedCountDownProcessEventListener.java +++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/test/util/ProcessCompletedCountDownProcessEventListener.java @@ -19,9 +19,13 @@ package org.jbpm.test.util; import org.kie.api.event.process.ProcessCompletedEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ProcessCompletedCountDownProcessEventListener extends DefaultCountDownProcessEventListener { + private static final Logger logger = LoggerFactory.getLogger(ProcessCompletedCountDownProcessEventListener.class); + public ProcessCompletedCountDownProcessEventListener() { super(1); } @@ -32,6 +36,7 @@ public ProcessCompletedCountDownProcessEventListener(int threads) { @Override public void afterProcessCompleted(ProcessCompletedEvent event) { + logger.info("process completed {}", event); countDown(); } diff --git a/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/integrationtests/handler/TestWorkItemHandler.java b/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/integrationtests/handler/TestWorkItemHandler.java index 3fd78aed428..8f768588113 100755 --- a/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/integrationtests/handler/TestWorkItemHandler.java +++ b/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/integrationtests/handler/TestWorkItemHandler.java @@ -18,20 +18,28 @@ */ package org.jbpm.integrationtests.handler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import java.util.Optional; -public class TestWorkItemHandler implements KogitoWorkItemHandler { +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; + +public class TestWorkItemHandler extends DefaultKogitoWorkItemHandler { private KogitoWorkItem workItem; private boolean aborted = false; - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { this.workItem = workItem; + return Optional.empty(); } - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { aborted = true; + return Optional.empty(); } public KogitoWorkItem getWorkItem() { diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/Work.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/Work.java index d4f7213a542..e6c22d9b6a0 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/Work.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/Work.java @@ -18,16 +18,15 @@ */ package org.jbpm.process.core; -import java.util.Collection; import java.util.Map; import java.util.Set; -import org.jbpm.process.instance.impl.humantask.DeadlineInfo; -import org.jbpm.process.instance.impl.humantask.Reassignment; import org.kie.kogito.process.workitems.WorkParametersFactory; public interface Work { + static final String PARAMETER_UNIQUE_TASK_ID = "UNIQUE_TASK_ID"; + void setName(String name); String getName(); @@ -52,32 +51,6 @@ public interface Work { Set getMetaParameters(); - /** - * Retrieve information about non started deadlines. - *

- * Deadline information consist of the expiration date (which can be a exact date - * or a potentially repeatable duration)and a list of key value pairs with arbitrary - * information about the notification itself. - * - * @return a collection containing deadline information. - */ - Collection>> getNotStartedDeadlines(); - - /** - * Retrieve information about non completed deadlines. - *

- * Deadline information consist of the expiration date (which can be a exact date - * or a potentially repeatable duration)and a list of key value pairs with arbitrary - * information about the notification itself. - * - * @return a collection containing deadline information. - */ - Collection>> getNotCompletedDeadlines(); - - Collection> getNotStartedReassignments(); - - Collection> getNotCompletedReassigments(); - void setWorkParametersFactory(WorkParametersFactory factory); WorkParametersFactory getWorkParametersFactory(); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ErrorCodeExceptionPolicy.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ErrorCodeExceptionPolicy.java index e07aa654bc5..787cd113c84 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ErrorCodeExceptionPolicy.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ErrorCodeExceptionPolicy.java @@ -18,7 +18,7 @@ */ package org.jbpm.process.core.context.exception; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; public class ErrorCodeExceptionPolicy extends AbstractRootCauseExceptionPolicy { diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ExceptionScope.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ExceptionScope.java index 5b749a02604..84fd76027ca 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ExceptionScope.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/ExceptionScope.java @@ -25,7 +25,7 @@ import org.jbpm.process.core.Context; import org.jbpm.process.core.context.AbstractContext; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/ExpressionEventTypeFilter.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/ExpressionEventTypeFilter.java index 3c62a8e935d..e3a3922e210 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/ExpressionEventTypeFilter.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/ExpressionEventTypeFilter.java @@ -37,7 +37,7 @@ public ExpressionEventTypeFilter(String type, ReturnValueEvaluator returnValueEv */ @Override public boolean acceptsEvent(String type, Object event, Function resolver) { - return (Boolean) returnValueEvaluator.eval(resolver); + return this.type.equals(type) && (Boolean) returnValueEvaluator.eval(resolver); } } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/impl/WorkImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/impl/WorkImpl.java index 98d0457733c..3cf83154343 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/impl/WorkImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/impl/WorkImpl.java @@ -19,7 +19,6 @@ package org.jbpm.process.core.impl; import java.io.Serializable; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -30,9 +29,6 @@ import org.jbpm.process.core.ParameterDefinition; import org.jbpm.process.core.Work; -import org.jbpm.process.instance.impl.humantask.DeadlineHelper; -import org.jbpm.process.instance.impl.humantask.DeadlineInfo; -import org.jbpm.process.instance.impl.humantask.Reassignment; import org.kie.kogito.process.workitems.WorkParametersFactory; public class WorkImpl implements Work, Serializable { @@ -43,27 +39,9 @@ public class WorkImpl implements Work, Serializable { private Map parameters = new LinkedHashMap<>(); private Map parameterDefinitions = new LinkedHashMap<>(); - private Collection>> startDeadlines; - private Collection>> endDeadlines; - private Collection> startReassigments; - private Collection> endReassigments; - private WorkParametersFactory factory; - private static final String NOT_STARTED = "NotStartedNotify"; - private static final String NOT_COMPLETED = "NotCompletedNotify"; - - private static final String NOT_STARTED_ASSIGN = "NotStartedReassign"; - private static final String NOT_COMPLETED_ASSIGN = "NotCompletedReassign"; - - private static final Set META_NAMES = new HashSet<>(); - - static { - META_NAMES.add(NOT_STARTED); - META_NAMES.add(NOT_COMPLETED); - META_NAMES.add(NOT_STARTED_ASSIGN); - META_NAMES.add(NOT_COMPLETED_ASSIGN); - } + private Set metaParameters = new HashSet<>(); @Override public void setName(String name) { @@ -104,6 +82,15 @@ public Map getParameters() { return Collections.unmodifiableMap(parameters); } + public void setMetaParameters(Set metaParameters) { + this.metaParameters = metaParameters; + } + + @Override + public Set getMetaParameters() { + return metaParameters; + } + @Override public String toString() { return "Work " + name; @@ -137,45 +124,6 @@ public ParameterDefinition getParameterDefinition(String name) { return parameterDefinitions.get(name); } - @Override - public Collection>> getNotStartedDeadlines() { - - if (startDeadlines == null) { - startDeadlines = DeadlineHelper.parseDeadlines(getParameter(NOT_STARTED)); - } - return startDeadlines; - - } - - @Override - public Collection>> getNotCompletedDeadlines() { - if (endDeadlines == null) { - endDeadlines = DeadlineHelper.parseDeadlines(getParameter(NOT_COMPLETED)); - } - return endDeadlines; - } - - @Override - public Set getMetaParameters() { - return META_NAMES; - } - - @Override - public Collection> getNotStartedReassignments() { - if (startReassigments == null) { - startReassigments = DeadlineHelper.parseReassignments(getParameter(NOT_STARTED_ASSIGN)); - } - return startReassigments; - } - - @Override - public Collection> getNotCompletedReassigments() { - if (endReassigments == null) { - endReassigments = DeadlineHelper.parseReassignments(getParameter(NOT_COMPLETED_ASSIGN)); - } - return endReassigments; - } - @Override public void setWorkParametersFactory(WorkParametersFactory factory) { this.factory = factory; @@ -186,4 +134,5 @@ public void setWorkParametersFactory(WorkParametersFactory factory) { public WorkParametersFactory getWorkParametersFactory() { return factory; } + } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntimeServiceProvider.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntimeServiceProvider.java index f55ae7b3d98..167740cdf9e 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntimeServiceProvider.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/AbstractProcessRuntimeServiceProvider.java @@ -26,7 +26,7 @@ import org.kie.kogito.auth.IdentityProvider; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; import org.kie.kogito.jobs.JobsService; import org.kie.kogito.process.ProcessEventListenerConfig; import org.kie.kogito.process.WorkItemHandlerConfig; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java index eff279bee51..ce4ef63213a 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java @@ -55,7 +55,7 @@ import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; import org.kie.kogito.jobs.JobsService; /** diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessRuntimeImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessRuntimeImpl.java index 39a724dee60..d7e7207faa3 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessRuntimeImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessRuntimeImpl.java @@ -30,7 +30,7 @@ import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; import org.kie.kogito.jobs.JobsService; public class KogitoProcessRuntimeImpl implements KogitoProcessRuntime { diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java index d5721f743d9..df1b7c5ba69 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java @@ -53,7 +53,7 @@ import org.kie.internal.runtime.StatefulKnowledgeSession; import org.kie.kogito.Application; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; import org.kie.kogito.jobs.DurationExpirationTime; import org.kie.kogito.jobs.ExactExpirationTime; import org.kie.kogito.jobs.ExpirationTime; 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 67cf635ebb8..16a1519fe48 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 @@ -18,37 +18,30 @@ */ package org.jbpm.process.instance; -import java.util.Arrays; +import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.stream.Stream; import org.drools.core.process.WorkItem; -import org.jbpm.process.instance.impl.workitem.Abort; -import org.jbpm.process.instance.impl.workitem.Active; -import org.jbpm.process.instance.impl.workitem.Complete; import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerNotFoundException; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; -import org.kie.kogito.process.workitems.KogitoWorkItemHandlerNotFoundException; -import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; import org.kie.kogito.signal.SignalManager; -import static org.jbpm.process.instance.impl.workitem.Abort.ID; -import static org.jbpm.process.instance.impl.workitem.Abort.STATUS; -import static org.kie.api.runtime.process.WorkItem.ABORTED; -import static org.kie.api.runtime.process.WorkItem.COMPLETED; +import static java.util.Collections.emptyMap; public class LightWorkItemManager implements InternalKogitoWorkItemManager { @@ -59,9 +52,6 @@ public class LightWorkItemManager implements InternalKogitoWorkItemManager { private final SignalManager signalManager; private final KogitoProcessEventSupport eventSupport; - private Complete completePhase = new Complete(); - private Abort abortPhase = new Abort(); - public LightWorkItemManager(ProcessInstanceManager processInstanceManager, SignalManager signalManager, KogitoProcessEventSupport eventSupport) { this.processInstanceManager = processInstanceManager; this.signalManager = signalManager; @@ -69,20 +59,13 @@ public LightWorkItemManager(ProcessInstanceManager processInstanceManager, Signa } @Override - public void internalExecuteWorkItem(InternalKogitoWorkItem workItem) { - internalAddWorkItem(workItem); - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); - Transition transition = new TransitionToActive(); - eventSupport.fireBeforeWorkItemTransition(processInstance, workItem, transition, null); - - handler.executeWorkItem(workItem, this); + public KogitoWorkItemHandler getKogitoWorkItemHandler(String name) { + return this.workItemHandlers.get(name); + } - eventSupport.fireAfterWorkItemTransition(processInstance, workItem, transition, null); - } else { - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); - } + @Override + public void registerWorkItemHandler(String workItemName, KogitoWorkItemHandler handler) { + this.workItemHandlers.put(workItemName, handler); } @Override @@ -91,174 +74,155 @@ public void internalAddWorkItem(InternalKogitoWorkItem workItem) { } @Override - public void internalAbortWorkItem(String id) { - InternalKogitoWorkItem workItem = workItems.get(id); - // work item may have been aborted - if (workItem != null) { - workItem.setCompleteDate(new Date()); - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - - KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); - Transition transition = new TransitionToAbort(Collections.emptyList()); - eventSupport.fireBeforeWorkItemTransition(processInstance, workItem, transition, null); - - handler.abortWorkItem(workItem, this); - workItem.setPhaseId(ID); - workItem.setPhaseStatus(STATUS); - eventSupport.fireAfterWorkItemTransition(processInstance, workItem, transition, null); - } else { - workItems.remove(workItem.getStringId()); - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); - } - workItems.remove(workItem.getStringId()); - } + public InternalKogitoWorkItem getWorkItem(String id) { + return workItems.get(id); } - public void retryWorkItem(String workItemId) { - InternalKogitoWorkItem workItem = workItems.get(workItemId); - retryWorkItem(workItem); + @Override + public void internalRemoveWorkItem(String id) { + workItems.remove(id); } - public void retryWorkItemWithParams(String workItemId, Map map) { - InternalKogitoWorkItem workItem = workItems.get(workItemId); - - if (workItem != null) { - workItem.setParameters(map); + @Override + public void internalExecuteWorkItem(InternalKogitoWorkItem workItem) { + internalAddWorkItem(workItem); + KogitoWorkItemHandler handler = getWorkItemHandler(workItem); + WorkItemTransition transition = handler.startingTransition(Collections.emptyMap()); + transitionWorkItem(workItem, transition, true); + } - retryWorkItem(workItem); + public KogitoWorkItemHandler getWorkItemHandler(String workItemId) throws KogitoWorkItemHandlerNotFoundException { + InternalKogitoWorkItem workItem = workItems.get(workItemId); + if (workItem == null) { + throw new WorkItemNotFoundException(workItemId); } + return getWorkItemHandler(workItem); } - private void retryWorkItem(InternalKogitoWorkItem workItem) { - if (workItem != null) { - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - handler.executeWorkItem(workItem, this); - } else - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + public KogitoWorkItemHandler getWorkItemHandler(InternalKogitoWorkItem workItem) throws KogitoWorkItemHandlerNotFoundException { + KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); + if (handler == null) { + throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); } + return handler; } @Override - public InternalKogitoWorkItem getWorkItem(String id) { - return workItems.get(id); + public void internalAbortWorkItem(String workItemId) { + InternalKogitoWorkItem workItem = getWorkItem(workItemId); + KogitoWorkItemHandler handler = getWorkItemHandler(workItem); + transitionWorkItem(workItem, handler.abortTransition(workItem.getPhaseStatus()), false); } @Override - public void internalRemoveWorkItem(String id) { - workItems.remove(id); - } + public void retryWorkItem(String workItemId, Map params) { + InternalKogitoWorkItem workItem = workItems.get(workItemId); - @Override - public void completeWorkItem(String id, Map results, Policy... policies) { - transitionWorkItem(id, new TransitionToComplete(results, Arrays.asList(policies))); - } + if (workItem == null) { + throw new WorkItemNotFoundException(workItemId); + } - @Override - public T updateWorkItem(String id, - Function updater, - Policy... policies) { - InternalKogitoWorkItem workItem = workItems.get(id); - if (workItem != null) { - if (!workItem.enforce(policies)) { - throw new NotAuthorizedException("User is not authorized to access task instance with id " + id); - } - T results = updater.apply(workItem); - eventSupport.fireAfterWorkItemTransition(processInstanceManager.getProcessInstance(workItem - .getProcessInstanceStringId()), workItem, null, null); - return results; - } else { - throw new WorkItemNotFoundException(id); + workItem.setPhaseId(null); + workItem.setPhaseStatus(null); + + if (params != null && !params.isEmpty()) { + workItem.setParameters(params); } + KogitoWorkItemHandler handler = getWorkItemHandler(workItem); + WorkItemTransition transition = handler.startingTransition(Collections.emptyMap()); + transitionWorkItem(workItem, transition, true); + } @Override - public void internalCompleteWorkItem(InternalKogitoWorkItem workItem) { + public void completeWorkItem(String workItemId, Map data, Policy... policies) { + InternalKogitoWorkItem workItem = getWorkItem(workItemId); + KogitoWorkItemHandler handler = getWorkItemHandler(workItem); + transitionWorkItem(workItem, handler.completeTransition(workItem.getPhaseStatus(), data, policies), false); + // process instance may have finished already KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); - workItem.setState(COMPLETED); - workItem.setCompleteDate(new Date()); + workItem.setState(KogitoWorkItem.COMPLETED); + processInstance.signalEvent("workItemCompleted", workItem); + + } + @Override + public void abortWorkItem(String workItemId, Policy... policies) { + InternalKogitoWorkItem workItem = getWorkItem(workItemId); + KogitoWorkItemHandler handler = getWorkItemHandler(workItemId); + transitionWorkItem(workItem, handler.abortTransition(workItem.getPhaseStatus(), policies), false); // process instance may have finished already - if (processInstance != null) { - processInstance.signalEvent("workItemCompleted", workItem); - } - workItems.remove(workItem.getStringId()); + KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); + workItem.setState(KogitoWorkItem.ABORTED); + processInstance.signalEvent("workItemAborted", workItem); } @Override - public void transitionWorkItem(String id, Transition transition) { - InternalKogitoWorkItem workItem = workItems.get(id); - if (workItem != null) { - transitionWorkItem(workItem, transition); - } else { - throw new WorkItemNotFoundException("Work Item (" + id + ") does not exist", id); + public T updateWorkItem(String workItemId, Function updater, Policy... policies) { + InternalKogitoWorkItem workItem = workItems.get(workItemId); + if (workItem == null) { + throw new WorkItemNotFoundException(workItemId); } - } + Stream.of(policies).forEach(p -> p.enforce(workItem)); + T results = updater.apply(workItem); + return results; - @SuppressWarnings("unchecked") - private void transitionWorkItem(InternalKogitoWorkItem workItem, Transition transition) { - // work item may have been aborted - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - KogitoProcessInstance processInstance = processInstanceManager - .getProcessInstance(workItem.getProcessInstanceStringId()); - eventSupport.fireBeforeWorkItemTransition(processInstance, workItem, transition, null); - try { - handler.transitionToPhase(workItem, this, transition); - } catch (UnsupportedOperationException ex) { - workItem.setResults((Map) transition.data()); - workItem.setPhaseId(Complete.ID); - workItem.setPhaseStatus(Complete.STATUS); - completePhase.apply(workItem, transition); - internalCompleteWorkItem(workItem); - } - processInstance.signalEvent("workItemTransition", transition); - eventSupport.fireAfterWorkItemTransition(processInstance, workItem, transition, null); - } else { - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); - } } @Override - public void abortWorkItem(String id, Policy... policies) { - KogitoWorkItemImpl workItem = (KogitoWorkItemImpl) workItems.get(id); - // work item may have been aborted - if (workItem != null) { - if (!workItem.enforce(policies)) { - throw new NotAuthorizedException("Work item can be aborted as it does not fulfil policies (e.g. security)"); - } - KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); - Transition transition = new TransitionToAbort(Arrays.asList(policies)); - eventSupport.fireBeforeWorkItemTransition(processInstance, workItem, transition, null); - workItem.setState(ABORTED); - abortPhase.apply(workItem, transition); - - // process instance may have finished already - if (processInstance != null) { - processInstance.signalEvent("workItemAborted", workItem); - } - workItem.setPhaseId(ID); - workItem.setPhaseStatus(STATUS); - eventSupport.fireAfterWorkItemTransition(processInstance, workItem, transition, null); - workItems.remove(id); - } + public void internalCompleteWorkItem(InternalKogitoWorkItem workItem) { + KogitoWorkItemHandler handler = getWorkItemHandler(workItem); + transitionWorkItem(workItem.getStringId(), handler.completeTransition(workItem.getPhaseStatus(), emptyMap())); } @Override - public void completeWorkItem(long l, Map map) { - throw new UnsupportedOperationException(); + 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); } @Override - public void abortWorkItem(long l) { - throw new UnsupportedOperationException(); + public Collection getHandlerIds() { + return this.workItemHandlers.keySet(); } - @Override - public void registerWorkItemHandler(String workItemName, KogitoWorkItemHandler handler) { - this.workItemHandlers.put(workItemName, handler); + private void transitionWorkItem(InternalKogitoWorkItem workItem, WorkItemTransition transition, boolean signal) { + // work item may have been aborted + KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); + if (handler == null) { + throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + } + + KogitoProcessInstance processInstance = processInstanceManager.getProcessInstance(workItem.getProcessInstanceStringId()); + WorkItemTransition lastTransition = null; + Optional nextTransition = Optional.of(transition); + while (nextTransition.isPresent()) { + lastTransition = nextTransition.get(); + this.eventSupport.fireBeforeWorkItemTransition(workItem.getProcessInstance(), workItem, lastTransition, null); + nextTransition = handler.transitionToPhase(this, workItem, nextTransition.get()); + processInstance.signalEvent("workItemTransition", transition); + 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; + } + } + } } @Override @@ -271,24 +235,15 @@ public void signalEvent(String type, Object event) { this.signalManager.signalEvent(type, event); } - @Override - public void dispose() { - throw new UnsupportedOperationException(); - } - @Override public void signalEvent(String type, Object event, String processInstanceId) { this.signalManager.signalEvent(processInstanceId, type, event); } + // deprecated functions @Override - public void retryWorkItem(String workItemID, Map params) { - if (params == null || params.isEmpty()) { - retryWorkItem(workItemID); - } else { - this.retryWorkItemWithParams(workItemID, params); - } - + public void dispose() { + throw new UnsupportedOperationException(); } @Override @@ -296,71 +251,14 @@ public Set getWorkItems() { throw new UnsupportedOperationException(); } - private static class TransitionToActive implements Transition { - - @Override - public String phase() { - return Active.ID; - } - - @Override - public Void data() { - return null; - } - - @Override - public List> policies() { - return Collections.emptyList(); - } - } - - private static class TransitionToAbort implements Transition { - - private List> policies; - - TransitionToAbort(List> policies) { - this.policies = policies; - } - - @Override - public String phase() { - return ID; - } - - @Override - public Void data() { - return null; - } - - @Override - public List> policies() { - return policies; - } + @Override + public void completeWorkItem(long l, Map map) { + throw new UnsupportedOperationException(); } - private static class TransitionToComplete implements Transition> { - private Map data; - private List> policies; - - TransitionToComplete(Map data, List> policies) { - this.data = data; - this.policies = policies; - } - - @Override - public String phase() { - return Complete.ID; - } - - @Override - public Map data() { - return data; - } - - @Override - public List> policies() { - return policies; - } + @Override + public void abortWorkItem(long l) { + throw new UnsupportedOperationException(); } } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/ProcessRuntimeServiceProvider.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/ProcessRuntimeServiceProvider.java index e2c01ffd62e..4017238479f 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/ProcessRuntimeServiceProvider.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/ProcessRuntimeServiceProvider.java @@ -19,7 +19,7 @@ package org.jbpm.process.instance; import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; import org.kie.kogito.jobs.JobsService; import org.kie.kogito.signal.SignalManager; import org.kie.kogito.uow.UnitOfWorkManager; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java index 18c4f882e64..e1142206cc9 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java @@ -41,11 +41,14 @@ import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.jbpm.process.core.context.exception.CompensationScope.IMPLICIT_COMPENSATION_PREFIX; public class CompensationScopeInstance extends ExceptionScopeInstance { + private static Logger LOG = LoggerFactory.getLogger(CompensationScopeInstance.class); private static final long serialVersionUID = 510l; private Stack compensationInstances = new Stack<>(); @@ -61,15 +64,16 @@ public void addCompensationInstances(Collection generatedInstances @Override public void handleException(String activityRef, KogitoProcessContext dunno) { + LOG.debug("Compensating exception {}", activityRef); + assert activityRef != null : "It should not be possible for the compensation activity reference to be null here."; CompensationScope compensationScope = (CompensationScope) getExceptionScope(); // broadcast/general compensation in reverse order if (activityRef.startsWith(IMPLICIT_COMPENSATION_PREFIX)) { activityRef = activityRef.substring(IMPLICIT_COMPENSATION_PREFIX.length()); - assert activityRef.equals(compensationScope.getContextContainerId()) - : "Compensation activity ref [" + activityRef + "] does not match" + - " Compensation Scope container id [" + compensationScope.getContextContainerId() + "]"; + assert activityRef.equals(compensationScope.getContextContainerId()) : "Compensation activity ref [" + activityRef + "] does not match" + + " Compensation Scope container id [" + compensationScope.getContextContainerId() + "]"; Map handlers = compensationScope.getExceptionHandlers(); List completedNodeIds = ((WorkflowProcessInstanceImpl) getProcessInstance()).getCompletedNodeIds(); @@ -98,6 +102,7 @@ public void handleException(String activityRef, KogitoProcessContext dunno) { } public void handleException(ExceptionHandler handler, String compensationActivityRef, KogitoProcessContext dunno) { + LOG.info("Compensating 2 exception {}", compensationActivityRef); WorkflowProcessInstanceImpl processInstance = (WorkflowProcessInstanceImpl) getProcessInstance(); NodeInstanceContainer nodeInstanceContainer = (NodeInstanceContainer) getContextInstanceContainer(); if (handler instanceof CompensationHandler) { @@ -124,8 +129,7 @@ public void handleException(ExceptionHandler handler, String compensationActivit eventNodeInstance.signalEvent("Compensation", compensationActivityRef); } } - assert handlerNode instanceof BoundaryEventNode || handlerNode instanceof EventSubProcessNode - : "Unexpected compensation handler node type : " + handlerNode.getClass().getSimpleName(); + assert handlerNode instanceof BoundaryEventNode || handlerNode instanceof EventSubProcessNode : "Unexpected compensation handler node type : " + handlerNode.getClass().getSimpleName(); } catch (Exception e) { throwWorkflowRuntimeException(nodeInstanceContainer, processInstance, "Unable to execute compensation.", e); } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/DefaultExceptionScopeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/DefaultExceptionScopeInstance.java index ee3e5c7d8c5..0b831b12d27 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/DefaultExceptionScopeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/DefaultExceptionScopeInstance.java @@ -27,9 +27,11 @@ import org.jbpm.process.instance.impl.Action; import org.jbpm.workflow.instance.NodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DefaultExceptionScopeInstance extends ExceptionScopeInstance { - + private static Logger LOG = LoggerFactory.getLogger(DefaultExceptionScopeInstance.class); private static final long serialVersionUID = 510l; @Override @@ -38,7 +40,7 @@ public String getContextType() { } public void handleException(ExceptionHandler handler, String exception, KogitoProcessContext params) { - + LOG.debug("exception handler {}", exception); if (handler instanceof ActionExceptionHandler) { ActionExceptionHandler exceptionHandler = (ActionExceptionHandler) handler; Action action = (Action) exceptionHandler.getAction().getMetaData("Action"); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java index 9d3f804397e..b6dcfc270e2 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java @@ -20,12 +20,9 @@ import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; import org.kie.api.event.process.MessageEvent; import org.kie.api.event.process.ProcessCompletedEvent; import org.kie.api.event.process.ProcessNodeLeftEvent; @@ -34,9 +31,6 @@ import org.kie.api.event.process.ProcessVariableChangedEvent; import org.kie.api.event.process.SLAViolatedEvent; import org.kie.api.event.process.SignalEvent; -import org.kie.api.event.usertask.UserTaskDeadlineEvent; -import org.kie.api.event.usertask.UserTaskDeadlineEvent.DeadlineType; -import org.kie.api.event.usertask.UserTaskVariableEvent.VariableEventType; import org.kie.api.runtime.KieRuntime; import org.kie.internal.runtime.Closeable; import org.kie.kogito.auth.IdentityProvider; @@ -45,11 +39,8 @@ import org.kie.kogito.internal.process.event.ProcessWorkItemTransitionEvent; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.Transition; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; public class KogitoProcessEventSupportImpl implements KogitoProcessEventSupport { @@ -187,13 +178,13 @@ public void fireAfterSLAViolated(final KogitoProcessInstance instance, KogitoNod } @Override - public void fireBeforeWorkItemTransition(final KogitoProcessInstance instance, KogitoWorkItem workitem, Transition transition, KieRuntime kruntime) { + public void fireBeforeWorkItemTransition(final KogitoProcessInstance instance, KogitoWorkItem workitem, WorkItemTransition transition, KieRuntime kruntime) { final ProcessWorkItemTransitionEvent event = new KogitoProcessWorkItemTransitionEventImpl(instance, workitem, transition, kruntime, false, identityProvider.getName()); notifyAllListeners(l -> l.beforeWorkItemTransition(event)); } @Override - public void fireAfterWorkItemTransition(final KogitoProcessInstance instance, KogitoWorkItem workitem, Transition transition, KieRuntime kruntime) { + public void fireAfterWorkItemTransition(final KogitoProcessInstance instance, KogitoWorkItem workitem, WorkItemTransition transition, KieRuntime kruntime) { final ProcessWorkItemTransitionEvent event = new KogitoProcessWorkItemTransitionEventImpl(instance, workitem, transition, kruntime, true, identityProvider.getName()); notifyAllListeners(l -> l.afterWorkItemTransition(event)); } @@ -216,158 +207,6 @@ public void fireOnMigration(final KogitoProcessInstance processInstance, KieRunt notifyAllListeners(l -> l.onMigration(event)); } - // users tasks events - @Override - public void fireOnUserTaskNotStartedDeadline(KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - HumanTaskWorkItem workItem, - Map notification, - KieRuntime kruntime) { - fireUserTaskNotification(instance, nodeInstance, workItem, notification, DeadlineType.Started, kruntime); - } - - @Override - public void fireOnUserTaskNotCompletedDeadline(KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - HumanTaskWorkItem workItem, - Map notification, - KieRuntime kruntime) { - fireUserTaskNotification(instance, nodeInstance, workItem, notification, DeadlineType.Completed, kruntime); - } - - private void fireUserTaskNotification(KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - HumanTaskWorkItem workItem, - Map notification, - DeadlineType type, - KieRuntime kruntime) { - UserTaskDeadlineEvent event = new UserTaskDeadlineEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, workItem, notification, type, kruntime, identityProvider.getName()); - notifyAllListeners(l -> l.onUserTaskDeadline(event)); - } - - @Override - public void fireOneUserTaskStateChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - String oldStatus, String newStatus) { - UserTaskStateEventImpl event = new UserTaskStateEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setOldStatus(oldStatus); - event.setNewStatus(newStatus); - notifyAllListeners(l -> l.onUserTaskState(event)); - } - - @Override - public void fireOnUserTaskAssignmentChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - AssignmentType assignmentType, - Set oldUsersId, Set newUsersId) { - UserTaskAssignmentEventImpl event = new UserTaskAssignmentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setAssignmentType(assignmentType.name()); - event.setOldUsersId(oldUsersId); - event.setNewUsersId(newUsersId); - notifyAllListeners(l -> l.onUserTaskAssignment(event)); - } - - @Override - public void fireOnUserTaskInputVariableChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - String variableName, Object newValue, Object oldValue) { - UserTaskVariableEventImpl event = new UserTaskVariableEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setVariableName(variableName); - event.setOldValue(oldValue); - event.setNewValue(newValue); - event.setVariableType(VariableEventType.INPUT); - notifyAllListeners(l -> l.onUserTaskInputVariable(event)); - } - - @Override - public void fireOnUserTaskOutputVariableChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - String variableName, Object newValue, Object oldValue) { - UserTaskVariableEventImpl event = new UserTaskVariableEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setVariableName(variableName); - event.setOldValue(oldValue); - event.setNewValue(newValue); - event.setVariableType(VariableEventType.OUTPUT); - notifyAllListeners(l -> l.onUserTaskOutputVariable(event)); - } - - @Override - public void fireOnUserTaskAttachmentAdded( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Attachment addedAttachment) { - - UserTaskAttachmentEventImpl event = new UserTaskAttachmentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setNewAttachment(addedAttachment); - notifyAllListeners(l -> l.onUserTaskAttachmentAdded(event)); - } - - @Override - public void fireOnUserTaskAttachmentChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Attachment oldAttachment, Attachment newAttachment) { - UserTaskAttachmentEventImpl event = new UserTaskAttachmentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setOldAttachment(oldAttachment); - event.setNewAttachment(newAttachment); - notifyAllListeners(l -> l.onUserTaskAttachmentChange(event)); - } - - @Override - public void fireOnUserTaskAttachmentDeleted( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Attachment deletedAttachment) { - UserTaskAttachmentEventImpl event = new UserTaskAttachmentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setOldAttachment(deletedAttachment); - notifyAllListeners(l -> l.onUserTaskAttachmentDeleted(event)); - } - - @Override - public void fireOnUserTaskCommentAdded( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Comment addedComment) { - UserTaskCommentEventImpl event = new UserTaskCommentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setNewComment(addedComment); - notifyAllListeners(l -> l.onUserTaskCommentAdded(event)); - } - - @Override - public void fireOnUserTaskCommentChange( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Comment oldComment, Comment newComment) { - UserTaskCommentEventImpl event = new UserTaskCommentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setOldComment(oldComment); - event.setNewComment(newComment); - notifyAllListeners(l -> l.onUserTaskCommentChange(event)); - } - - @Override - public void fireOnUserTaskCommentDeleted( - KogitoProcessInstance instance, - KogitoNodeInstance nodeInstance, - KieRuntime kruntime, - Comment deletedComment) { - UserTaskCommentEventImpl event = new UserTaskCommentEventImpl(instance, (HumanTaskNodeInstance) nodeInstance, kruntime, identityProvider.getName()); - event.setOldComment(deletedComment); - notifyAllListeners(l -> l.onUserTaskCommentDeleted(event)); - } - @Override public void reset() { this.clear(); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessWorkItemTransitionEventImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessWorkItemTransitionEventImpl.java index 61353ffaf39..228f74bd06a 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessWorkItemTransitionEventImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessWorkItemTransitionEventImpl.java @@ -21,18 +21,18 @@ import org.kie.api.runtime.KieRuntime; import org.kie.api.runtime.process.ProcessInstance; import org.kie.kogito.internal.process.event.ProcessWorkItemTransitionEvent; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.Transition; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; public class KogitoProcessWorkItemTransitionEventImpl extends ProcessEvent implements ProcessWorkItemTransitionEvent { private static final long serialVersionUID = 510l; private KogitoWorkItem workItem; - private Transition transition; + private WorkItemTransition transition; private boolean transitioned; - public KogitoProcessWorkItemTransitionEventImpl(ProcessInstance instance, KogitoWorkItem workItem, Transition transition, KieRuntime kruntime, boolean transitioned, String identity) { + public KogitoProcessWorkItemTransitionEventImpl(ProcessInstance instance, KogitoWorkItem workItem, WorkItemTransition transition, KieRuntime kruntime, boolean transitioned, String identity) { super(instance, kruntime, identity); this.workItem = workItem; this.transition = transition; @@ -48,13 +48,13 @@ public KogitoWorkItem getWorkItem() { public String toString() { StringBuilder sb = new StringBuilder("==>[WorkItemTransition(id=" + getWorkItem().getStringId()); if (transition != null) { - sb.append(" phase=" + transition.phase() + ")]"); + sb.append(" phase=" + transition.id() + ")]"); } return sb.toString(); } @Override - public Transition getTransition() { + public WorkItemTransition getTransition() { return transition; } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAttachmentEventImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAttachmentEventImpl.java deleted file mode 100644 index 34d4f699627..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAttachmentEventImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.jbpm.process.instance.event; - -import java.net.URI; -import java.util.Date; - -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskAttachmentEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; -import org.kie.kogito.process.workitem.Attachment; - -public class UserTaskAttachmentEventImpl extends UserTaskEventImpl implements UserTaskAttachmentEvent { - - private static final long serialVersionUID = 3956348350804141924L; - private Attachment oldAttachment; - private Attachment newAttachment; - - public UserTaskAttachmentEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime, String user) { - super(instance, nodeInstance, kruntime, user); - } - - public void setOldAttachment(Attachment oldAttachment) { - this.oldAttachment = oldAttachment; - } - - public void setNewAttachment(Attachment newAttachment) { - this.newAttachment = newAttachment; - } - - @Override - public org.kie.api.event.usertask.Attachment getOldAttachment() { - return wrap(oldAttachment); - } - - @Override - public org.kie.api.event.usertask.Attachment getNewAttachment() { - return wrap(newAttachment); - } - - private org.kie.api.event.usertask.Attachment wrap(Attachment attachment) { - if (attachment == null) { - return null; - } - return new org.kie.api.event.usertask.Attachment() { - - @Override - public String getAttachmentId() { - return attachment.getId(); - } - - @Override - public String getAttachmentName() { - return attachment.getName(); - } - - @Override - public URI getAttachmentURI() { - return attachment.getContent(); - } - - @Override - public String getUpdatedBy() { - return attachment.getUpdatedBy(); - } - - @Override - public Date getUpdatedAt() { - return attachment.getUpdatedAt(); - } - - }; - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskCommentEventImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskCommentEventImpl.java deleted file mode 100644 index 4bf5b512f60..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskCommentEventImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.jbpm.process.instance.event; - -import java.util.Date; - -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskCommentEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; -import org.kie.kogito.process.workitem.Comment; - -public class UserTaskCommentEventImpl extends UserTaskEventImpl implements UserTaskCommentEvent { - - private static final long serialVersionUID = -7962827076724999755L; - private Comment oldComment; - private Comment newComment; - - public UserTaskCommentEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime, String user) { - super(instance, nodeInstance, kruntime, user); - } - - @Override - public String getUserTaskId() { - return getHumanTaskNodeInstance().getWorkItemId(); - } - - public void setOldComment(Comment oldComment) { - this.oldComment = oldComment; - } - - public void setNewComment(Comment newComment) { - this.newComment = newComment; - } - - @Override - public org.kie.api.event.usertask.Comment getNewComment() { - return wrap(newComment); - } - - @Override - public org.kie.api.event.usertask.Comment getOldComment() { - return wrap(oldComment); - } - - private org.kie.api.event.usertask.Comment wrap(Comment comment) { - if (comment == null) { - return null; - } - - return new org.kie.api.event.usertask.Comment() { - - @Override - public String getCommentId() { - return comment.getId(); - } - - @Override - public String getCommentContent() { - return comment.getContent(); - } - - @Override - public String getUpdatedBy() { - return comment.getUpdatedBy(); - } - - @Override - public Date getUpdatedAt() { - return comment.getUpdatedAt(); - } - - }; - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskEventImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskEventImpl.java deleted file mode 100644 index dbc1920502f..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskEventImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.jbpm.process.instance.event; - -import java.util.Date; -import java.util.EventObject; - -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; - -public class UserTaskEventImpl extends EventObject implements UserTaskEvent { - - private static final long serialVersionUID = 510l; - - private final KieRuntime kruntime; - private final Date eventDate; - private final String eventUser; - - private HumanTaskNodeInstance humanTaskNodeInstance; - - public UserTaskEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime) { - this(instance, nodeInstance, kruntime, null); - } - - public UserTaskEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime, String user) { - super(instance); - this.humanTaskNodeInstance = nodeInstance; - this.kruntime = kruntime; - this.eventDate = new Date(); - this.eventUser = user; - } - - public ProcessInstance getProcessInstance() { - return (ProcessInstance) getSource(); - } - - @Override - public HumanTaskNodeInstance getNodeInstance() { - return humanTaskNodeInstance; - } - - @Override - public InternalHumanTaskWorkItem getWorkItem() { - return humanTaskNodeInstance.getWorkItem(); - } - - @Override - public String getUserTaskId() { - return getWorkItem().getStringId(); - } - - @Override - public KieRuntime getKieRuntime() { - return kruntime; - } - - public HumanTaskNodeInstance getHumanTaskNodeInstance() { - return humanTaskNodeInstance; - } - - @Override - public Date getEventDate() { - return this.eventDate; - } - - @Override - public String getEventUser() { - return eventUser; - } - - @Override - public String getUserTaskDefinitionId() { - return getHumanTaskNodeInstance().getNodeDefinitionId(); - } - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/SignalProcessInstanceAction.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/SignalProcessInstanceAction.java index fe693e1cd76..416b12d055f 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/SignalProcessInstanceAction.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/SignalProcessInstanceAction.java @@ -31,9 +31,13 @@ import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SignalProcessInstanceAction implements Action, Serializable { + private static final Logger LOG = LoggerFactory.getLogger(SignalProcessInstanceAction.class); + public static final String DEFAULT_SCOPE = "default"; public static final String PROCESS_INSTANCE_SCOPE = "processInstance"; public static final String EXTERNAL_SCOPE = "external"; @@ -102,6 +106,7 @@ public void execute(KogitoProcessContext context) throws Exception { String signalName = VariableUtil.resolveVariable(this.signalNameTemplate, context.getNodeInstance()); context.getKogitoProcessRuntime().getProcessEventSupport() .fireOnSignal(processInstance, nodeInstance, context.getKieRuntime(), signalName, signal); + LOG.debug("about to signal {} process {} with scope {}", signalName, processInstance.getId(), scope); if (DEFAULT_SCOPE.equals(scope)) { context.getKogitoProcessRuntime().signalEvent(signalName, signal); } else if (PROCESS_INSTANCE_SCOPE.equals(scope)) { @@ -112,6 +117,7 @@ public void execute(KogitoProcessContext context) throws Exception { workItem.setName("External Send Task"); workItem.setNodeInstanceId(context.getNodeInstance().getStringId()); workItem.setProcessInstanceId(context.getProcessInstance().getStringId()); + workItem.setProcessInstance(processInstance); workItem.setNodeId(context.getNodeInstance().getNodeId()); workItem.getParameters().putAll(inputSet); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandler.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandler.java deleted file mode 100755 index 403f93c5a5f..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandler.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.demo; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.ListSelectionModel; -import javax.swing.WindowConstants; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; - -/** - * - */ -public class UIWorkItemHandler extends JFrame implements KogitoWorkItemHandler { - - private static final long serialVersionUID = 510l; - - private Map workItems = new HashMap<>(); - private JList workItemsList; - private JButton selectButton; - - public UIWorkItemHandler() { - setSize(new Dimension(400, 300)); - setTitle("Work Items"); - setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - initializeComponent(); - } - - private void initializeComponent() { - JPanel panel = new JPanel(); - panel.setLayout(new GridBagLayout()); - getRootPane().setLayout(new BorderLayout()); - getRootPane().add(panel, BorderLayout.CENTER); - - workItemsList = new JList(); - workItemsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - workItemsList.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - select(); - } - } - }); - workItemsList.addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - selectButton.setEnabled(getSelectedWorkItem() != null); - } - }); - reloadWorkItemsList(); - GridBagConstraints c = new GridBagConstraints(); - c.weightx = 1; - c.weighty = 1; - c.fill = GridBagConstraints.BOTH; - c.insets = new Insets(5, 5, 5, 5); - panel.add(workItemsList, c); - - selectButton = new JButton("Select"); - selectButton.setEnabled(false); - selectButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - select(); - } - }); - c = new GridBagConstraints(); - c.gridy = 1; - c.weightx = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(5, 5, 5, 5); - panel.add(selectButton, c); - } - - private void select() { - KogitoWorkItem workItem = getSelectedWorkItem(); - if (workItem != null) { - UIWorkItemHandlerDialog dialog = new UIWorkItemHandlerDialog(UIWorkItemHandler.this, workItem); - dialog.setVisible(true); - } - } - - public KogitoWorkItem getSelectedWorkItem() { - int index = workItemsList.getSelectedIndex(); - if (index != -1) { - Object selected = workItemsList.getModel().getElementAt(index); - if (selected instanceof WorkItemWrapper) { - return ((WorkItemWrapper) selected).getWorkItem(); - } - } - return null; - } - - private void reloadWorkItemsList() { - List result = new ArrayList<>(); - for (KogitoWorkItem workItem : workItems.keySet()) { - result.add(new WorkItemWrapper(workItem)); - } - workItemsList.setListData(result.toArray()); - } - - public void complete(KogitoWorkItem workItem, Map results) { - KogitoWorkItemManager manager = workItems.get(workItem); - if (manager != null) { - manager.completeWorkItem(workItem.getStringId(), results); - workItems.remove(workItem); - reloadWorkItemsList(); - } - selectButton.setEnabled(getSelectedWorkItem() != null); - } - - public void abort(KogitoWorkItem workItem) { - KogitoWorkItemManager manager = workItems.get(workItem); - if (manager != null) { - manager.abortWorkItem(workItem.getStringId()); - workItems.remove(workItem); - reloadWorkItemsList(); - } - selectButton.setEnabled(getSelectedWorkItem() != null); - } - - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - workItems.remove(workItem); - reloadWorkItemsList(); - } - - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - workItems.put(workItem, manager); - reloadWorkItemsList(); - } - - private class WorkItemWrapper { - - private KogitoWorkItem workItem; - - public WorkItemWrapper(KogitoWorkItem workItem) { - this.workItem = workItem; - } - - public KogitoWorkItem getWorkItem() { - return workItem; - } - - public String toString() { - return workItem.getName() + " [" + workItem.getStringId() + "]"; - } - } - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandlerDialog.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandlerDialog.java deleted file mode 100755 index 89bd5d5e632..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/UIWorkItemHandlerDialog.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.demo; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextArea; -import javax.swing.JTextField; - -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; - -/** - * - */ -public class UIWorkItemHandlerDialog extends JDialog { - - private static final long serialVersionUID = 510l; - - private Map results = new HashMap<>(); - private UIWorkItemHandler handler; - private KogitoWorkItem workItem; - private JTextField resultNameTextField; - private JTextField resultValueTextField; - private JButton addResultButton; - private JButton completeButton; - private JButton abortButton; - - public UIWorkItemHandlerDialog(UIWorkItemHandler handler, KogitoWorkItem workItem) { - super(handler, "Execute Work Item", true); - this.handler = handler; - this.workItem = workItem; - setSize(new Dimension(400, 300)); - initializeComponent(); - } - - private void initializeComponent() { - JPanel panel = new JPanel(); - panel.setLayout(new GridBagLayout()); - getRootPane().setLayout(new BorderLayout()); - getRootPane().add(panel, BorderLayout.CENTER); - - JTextArea params = new JTextArea(); - params.setText(getParameters()); - params.setEditable(false); - GridBagConstraints c = new GridBagConstraints(); - c.weightx = 1; - c.weighty = 1; - c.gridwidth = 5; - c.fill = GridBagConstraints.BOTH; - c.insets = new Insets(5, 5, 5, 5); - panel.add(params, c); - - JLabel resultName = new JLabel("Result"); - c = new GridBagConstraints(); - c.gridy = 1; - c.insets = new Insets(5, 5, 5, 5); - panel.add(resultName, c); - resultNameTextField = new JTextField(); - c = new GridBagConstraints(); - c.gridx = 1; - c.gridy = 1; - c.weightx = 0.3; - c.fill = GridBagConstraints.HORIZONTAL; - c.insets = new Insets(5, 5, 5, 5); - panel.add(resultNameTextField, c); - - JLabel resultValue = new JLabel("Value"); - c = new GridBagConstraints(); - c.gridx = 2; - c.gridy = 1; - c.insets = new Insets(5, 5, 5, 5); - panel.add(resultValue, c); - resultValueTextField = new JTextField(); - c = new GridBagConstraints(); - c.gridx = 3; - c.gridy = 1; - c.weightx = 0.7; - c.fill = GridBagConstraints.HORIZONTAL; - c.insets = new Insets(5, 5, 5, 5); - panel.add(resultValueTextField, c); - - addResultButton = new JButton("Add"); - addResultButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - addResult(); - } - }); - c = new GridBagConstraints(); - c.gridx = 4; - c.gridy = 1; - c.insets = new Insets(5, 5, 5, 5); - panel.add(addResultButton, c); - - completeButton = new JButton("Complete"); - completeButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - complete(); - } - }); - c = new GridBagConstraints(); - c.gridy = 2; - c.weightx = 1; - c.gridwidth = 4; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(5, 5, 5, 5); - panel.add(completeButton, c); - - abortButton = new JButton("Abort"); - abortButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - abort(); - } - }); - c = new GridBagConstraints(); - c.gridx = 4; - c.gridy = 2; - c.insets = new Insets(5, 5, 5, 5); - panel.add(abortButton, c); - } - - private String getParameters() { - StringBuilder result = new StringBuilder(); - if (workItem.getParameters() != null) { - for (Iterator> iterator = workItem.getParameters().entrySet().iterator(); iterator.hasNext();) { - Map.Entry entry = iterator.next(); - result.append(entry.getKey()).append(" = ").append(entry.getValue()).append("\n"); - } - } - return result.toString(); - } - - private void addResult() { - results.put(resultNameTextField.getText(), resultValueTextField.getText()); - resultNameTextField.setText(""); - resultValueTextField.setText(""); - } - - private void complete() { - handler.complete(workItem, results); - dispose(); - } - - private void abort() { - handler.abort(workItem); - dispose(); - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/BaseHumanTaskLifeCycle.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/BaseHumanTaskLifeCycle.java deleted file mode 100644 index da143b94bf4..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/BaseHumanTaskLifeCycle.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.jbpm.process.instance.impl.humantask.phases.Claim; -import org.jbpm.process.instance.impl.humantask.phases.Release; -import org.jbpm.process.instance.impl.humantask.phases.Skip; -import org.jbpm.process.instance.impl.workitem.Abort; -import org.jbpm.process.instance.impl.workitem.Active; -import org.jbpm.process.instance.impl.workitem.Complete; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; -import org.kie.kogito.process.workitem.InvalidTransitionException; -import org.kie.kogito.process.workitem.LifeCycle; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; -import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base life cycle definition for human tasks. It comes with following phases - * - *

    - *
  • Active
  • - *
  • Claim
  • - *
  • Release
  • - *
  • Complete
  • - *
  • Skip
  • - *
  • Abort
  • - *
- * At the beginning human task enters - * - *
- * Active
- * 
- * - * phase. From there it can go to - * - *
    - *
  • Claim
  • - *
  • Complete
  • - *
  • Skip
  • - *
  • Abort
  • - *
- * - * at any time. At each phase data can be associated and by that set on work item. - */ -public class BaseHumanTaskLifeCycle implements LifeCycle> { - - private static final Logger logger = LoggerFactory.getLogger(BaseHumanTaskLifeCycle.class); - - private Map phases = new LinkedHashMap<>(); - - public BaseHumanTaskLifeCycle() { - phases.put(Claim.ID, new Claim()); - phases.put(Release.ID, new Release()); - phases.put(Complete.ID, new Complete()); - phases.put(Skip.ID, new Skip()); - phases.put(Active.ID, new Active()); - phases.put(Abort.ID, new Abort()); - } - - @Override - public LifeCyclePhase phaseById(String phaseId) { - return phases.get(phaseId); - } - - @Override - public Collection phases() { - return phases.values(); - } - - @Override - public Map transitionTo(KogitoWorkItem workItem, KogitoWorkItemManager manager, Transition> transition) { - logger.debug("Transition method invoked for work item {} to transition to {}, currently in phase {} and status {}", workItem.getStringId(), transition.phase(), workItem.getPhaseId(), - workItem.getPhaseStatus()); - InternalHumanTaskWorkItem humanTaskWorkItem = (InternalHumanTaskWorkItem) workItem; - - LifeCyclePhase targetPhase = phases.get(transition.phase()); - if (targetPhase == null) { - logger.debug("Target life cycle phase '{}' does not exist in {}", transition.phase(), this.getClass().getSimpleName()); - throw new InvalidLifeCyclePhaseException(transition.phase()); - } - - LifeCyclePhase currentPhase = phases.get(humanTaskWorkItem.getPhaseId()); - - if (!targetPhase.canTransition(currentPhase)) { - logger.debug("Target life cycle phase '{}' cannot transition from current state '{}'", targetPhase.id(), currentPhase.id()); - throw new InvalidTransitionException("Cannot transition from " + humanTaskWorkItem.getPhaseId() + " to " + targetPhase.id()); - } - - if (!targetPhase.id().equals(Active.ID) && !targetPhase.id().equals(Abort.ID) && !humanTaskWorkItem.enforce(transition.policies().toArray(new Policy[transition.policies().size()]))) { - throw new NotAuthorizedException("User is not authorized to access task instance with id " + humanTaskWorkItem.getStringId()); - } - - humanTaskWorkItem.setPhaseId(targetPhase.id()); - humanTaskWorkItem.setPhaseStatus(targetPhase.status()); - - targetPhase.apply(humanTaskWorkItem, transition); - if (transition.data() != null) { - logger.debug("Updating data for phase {} and work item {}", targetPhase.id(), humanTaskWorkItem.getStringId()); - humanTaskWorkItem.setResults(transition.data()); - } - logger.debug("Transition for work item {} to {} done, currently in phase {} and status {}", workItem.getStringId(), transition.phase(), workItem.getPhaseId(), workItem.getPhaseStatus()); - - if (targetPhase.isTerminating()) { - logger.debug("Target life cycle phase '{}' is terminiating, completing work item {}", targetPhase.id(), humanTaskWorkItem.getStringId()); - // since target life cycle phase is terminating completing work item - ((InternalKogitoWorkItemManager) manager).internalCompleteWorkItem(humanTaskWorkItem); - } - - return data(humanTaskWorkItem); - } - - @Override - public Map data(KogitoWorkItem workItem) { - - return workItem.getResults(); - } - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskHelper.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskHelper.java deleted file mode 100644 index 7647ab7af2f..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskHelper.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask; - -import java.io.Serializable; -import java.nio.file.Paths; -import java.util.Date; -import java.util.Map; -import java.util.UUID; - -import org.jbpm.workflow.instance.NodeInstance; -import org.jbpm.workflow.instance.node.WorkItemNodeInstance; -import org.kie.kogito.MapOutput; -import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; -import org.kie.kogito.process.ProcessInstance; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.AttachmentInfo; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.TaskMetaEntity; - -public class HumanTaskHelper { - - private HumanTaskHelper() { - } - - public static InternalHumanTaskWorkItem decorate(NodeInstance nodeInstance, InternalHumanTaskWorkItem delegate) { - return new HumanTaskWorkItemDecoratorImpl(nodeInstance, delegate); - } - - public static InternalHumanTaskWorkItem asHumanTask(KogitoWorkItem item) { - if (item instanceof InternalHumanTaskWorkItem) { - return (InternalHumanTaskWorkItem) item; - } else { - throw new IllegalArgumentException("Work item " + item.getStringId() + " is not a human task"); - } - } - - public static Comment addComment(KogitoWorkItem item, String commentInfo, String user) { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - String id = getNewId(); - Comment comment = buildComment(id, commentInfo, user); - humanTask.setComment(id, comment); - return comment; - } - - public static Attachment addAttachment(KogitoWorkItem item, AttachmentInfo attachmentInfo, String user) { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - String id = getNewId(); - Attachment attachment = buildAttachment(id, attachmentInfo, user); - humanTask.setAttachment(id, attachment); - return attachment; - } - - public static Comment updateComment(KogitoWorkItem item, String id, String commentInfo, String user) { - try { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - Comment comment = humanTask.getComments().get(id); - if (comment == null) { - throw new IllegalArgumentException("Comment " + id + " does not exist"); - } - if (!comment.getUpdatedBy().equals(user)) { - throw new IllegalArgumentException("User " + user + " did not create the comment, cannot modify it"); - } - comment = comment.clone(); - humanTask.setComment(id, fillTaskMetaEntity(comment, commentInfo)); - return comment; - } catch (CloneNotSupportedException e) { - throw new IllegalArgumentException("Attachment could not be modified", e); - } - } - - public static Attachment updateAttachment(KogitoWorkItem item, - String id, - AttachmentInfo attachmentInfo, - String user) { - try { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - Attachment attachment = humanTask.getAttachments().get(id); - if (attachment == null) { - throw new IllegalArgumentException("Attachment " + id + " does not exist"); - } - if (!attachment.getUpdatedBy().equals(user)) { - throw new IllegalArgumentException("User " + user + " did not create the attachment, cannot modify it"); - } - - attachment = attachment.clone(); - humanTask.setAttachment(id, setAttachmentName(fillTaskMetaEntity(attachment, attachmentInfo.getUri()), attachmentInfo)); - return attachment; - } catch (CloneNotSupportedException e) { - throw new IllegalArgumentException("Attachment could not be modified", e); - } - - } - - public static Map updateContent(KogitoWorkItem item, MapOutput model) { - return updateContent(item, model.toMap()); - } - - public static Map updateContent(KogitoWorkItem item, Map map) { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - humanTask.setResults(map); - return humanTask.getResults(); - } - - public static boolean deleteComment(KogitoWorkItem item, Object id, String user) { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - Map comments = humanTask.getComments(); - Comment comment = comments.get(id); - if (comment == null || !comment.getUpdatedBy().equals(user)) { - return false; - } - return humanTask.removeComment((String) id) != null; - } - - public static boolean deleteAttachment(KogitoWorkItem item, Object id, String user) { - InternalHumanTaskWorkItem humanTask = asHumanTask(item); - Map attachments = humanTask.getAttachments(); - Attachment attachment = attachments.get(id); - if (attachment == null || !attachment.getUpdatedBy().equals(user)) { - return false; - } - return humanTask.removeAttachment((String) id) != null; - } - - public static HumanTaskWorkItem findTask(ProcessInstance pi, String taskId, Policy... policies) { - return pi.findNodes(ni -> isSearchWorkItem(ni, taskId, - policies)).stream().findFirst().map(wi -> (HumanTaskWorkItem) ((WorkItemNodeInstance) wi).getWorkItem()) - .orElseThrow(() -> new WorkItemNotFoundException(taskId)); - } - - private static boolean isSearchWorkItem(KogitoNodeInstance ni, String taskId, Policy... policies) { - return ni instanceof WorkItemNodeInstance && ((WorkItemNodeInstance) ni).getWorkItemId().equals( - taskId) && ((WorkItemNodeInstance) ni).getWorkItem().enforce(policies) && - ((WorkItemNodeInstance) ni).getWorkItem() instanceof HumanTaskWorkItem; - } - - private static Comment buildComment(String id, String content, String user) { - return fillTaskMetaEntity(new Comment(id, user), content); - } - - private static Attachment buildAttachment(String id, AttachmentInfo attachmentInfo, String user) { - return setAttachmentName(fillTaskMetaEntity(new Attachment(id, user), attachmentInfo.getUri()), attachmentInfo); - } - - private static Attachment setAttachmentName(Attachment attachment, AttachmentInfo attachmentInfo) { - String name = attachmentInfo.getName(); - if (name == null) { - name = Paths.get(attachmentInfo.getUri()).getFileName().toString(); - } - attachment.setName(name); - return attachment; - } - - private static > C fillTaskMetaEntity(C metaInfo, - T content) { - metaInfo.setUpdatedAt(new Date()); - metaInfo.setContent(content); - return metaInfo; - } - - private static String getNewId() { - return UUID.randomUUID().toString(); - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskTransition.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskTransition.java deleted file mode 100644 index b8b5ebf5c4e..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskTransition.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.kie.kogito.MapOutput; -import org.kie.kogito.auth.IdentityProvider; -import org.kie.kogito.auth.SecurityPolicy; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; - -/** - * Human task dedicated transition what uses Map of objects to be - * associated with work item - human task work item. - * - */ -public class HumanTaskTransition implements Transition> { - - private String phase; - private Map data; - private List> policies = new ArrayList<>(); - - public static HumanTaskTransition withModel(String phase, MapOutput data, Policy... policies) { - return new HumanTaskTransition(phase, data.toMap(), policies); - } - - public static HumanTaskTransition withoutModel(String phase, Policy... policies) { - return new HumanTaskTransition(phase, Collections.emptyMap(), policies); - } - - public HumanTaskTransition(String phase) { - this(phase, Collections.emptyMap()); - } - - public HumanTaskTransition(String phase, Map data, IdentityProvider identity) { - this(phase, data, SecurityPolicy.of(identity)); - } - - public HumanTaskTransition(String phase, Map data, Policy... policies) { - this.phase = phase; - this.data = data; - for (Policy policy : policies) { - this.policies.add(policy); - } - } - - @Override - public String phase() { - return phase; - } - - @Override - public Map data() { - return data; - } - - @Override - public List> policies() { - return policies; - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java deleted file mode 100644 index 4f22848d30f..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import org.drools.core.common.InternalKnowledgeRuntime; -import org.jbpm.process.instance.InternalProcessRuntime; -import org.jbpm.workflow.instance.NodeInstance; -import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl; -import org.kie.api.definition.process.WorkflowElementIdentifier; -import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; -import org.kie.kogito.internal.process.event.KogitoProcessEventSupport.AssignmentType; -import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.Policy; - -public class HumanTaskWorkItemDecoratorImpl implements InternalHumanTaskWorkItem { - - private NodeInstance nodeInstance; - private InternalHumanTaskWorkItem delegate; - - public HumanTaskWorkItemDecoratorImpl(NodeInstance nodeInstance, InternalHumanTaskWorkItem delegate) { - this.nodeInstance = nodeInstance; - this.delegate = delegate; - } - - private InternalKnowledgeRuntime getKieRuntime() { - return ((WorkflowProcessInstanceImpl) nodeInstance.getProcessInstance()).getKnowledgeRuntime(); - } - - private Optional getEventSupport() { - if (!isActive()) { - return Optional.empty(); - } - - if (getKieRuntime() == null) { - return Optional.empty(); - } - - if (getKieRuntime().getProcessRuntime() == null) { - return Optional.empty(); - } - - return Optional.of(InternalProcessRuntime.asKogitoProcessRuntime(getKieRuntime().getProcessRuntime()).getProcessEventSupport()); - } - - private boolean isActive() { - return nodeInstance.getProcessInstance() != null && getKieRuntime() != null; - } - - @Override - public String getTaskName() { - return delegate.getTaskName(); - } - - @Override - public String getTaskDescription() { - return delegate.getTaskDescription(); - } - - @Override - public String getTaskPriority() { - return delegate.getTaskPriority(); - } - - @Override - public String getReferenceName() { - return delegate.getReferenceName(); - } - - @Override - public String getActualOwner() { - return delegate.getActualOwner(); - } - - @Override - public Set getPotentialUsers() { - return delegate.getPotentialUsers(); - } - - @Override - public Set getPotentialGroups() { - return delegate.getPotentialGroups(); - } - - @Override - public Set getAdminUsers() { - return delegate.getAdminUsers(); - } - - @Override - public Set getAdminGroups() { - return delegate.getAdminGroups(); - } - - @Override - public Set getExcludedUsers() { - return delegate.getExcludedUsers(); - } - - @Override - public void setId(String uuid) { - delegate.setId(uuid); - } - - @Override - public void setAttachment(String id, Attachment attachment) { - Attachment oldValue = delegate.getAttachments().get(id); - delegate.setAttachment(id, attachment); - if (oldValue != null) { - getEventSupport().ifPresent(e -> e.fireOnUserTaskAttachmentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), oldValue, attachment)); - } else { - getEventSupport().ifPresent(e -> e.fireOnUserTaskAttachmentAdded(getProcessInstance(), getNodeInstance(), getKieRuntime(), attachment)); - } - } - - @Override - public Attachment removeAttachment(String id) { - Attachment oldValue = delegate.getAttachments().remove(id); - getEventSupport().ifPresent(e -> e.fireOnUserTaskAttachmentDeleted(getProcessInstance(), getNodeInstance(), getKieRuntime(), oldValue)); - return oldValue; - } - - @Override - public void setComment(String id, Comment comment) { - Comment oldValue = delegate.getComments().remove(id); - delegate.setComment(id, comment); - if (oldValue != null) { - getEventSupport().ifPresent(e -> e.fireOnUserTaskCommentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), oldValue, comment)); - } else { - getEventSupport().ifPresent(e -> e.fireOnUserTaskCommentAdded(getProcessInstance(), getNodeInstance(), getKieRuntime(), comment)); - } - - } - - @Override - public Comment removeComment(String id) { - Comment oldValue = delegate.getComments().remove(id); - getEventSupport().ifPresent(e -> e.fireOnUserTaskCommentDeleted(getProcessInstance(), getNodeInstance(), getKieRuntime(), oldValue)); - return oldValue; - } - - @Override - public Map getAttachments() { - return delegate.getAttachments(); - } - - @Override - public Map getComments() { - return delegate.getComments(); - } - - @Override - public long getId() { - return delegate.getId(); - } - - @Override - public String getStringId() { - return delegate.getStringId(); - } - - @Override - public String getProcessInstanceStringId() { - return delegate.getProcessInstanceId(); - } - - @Override - public String getPhaseId() { - return delegate.getPhaseId(); - } - - @Override - public String getPhaseStatus() { - return delegate.getPhaseStatus(); - } - - @Override - public Date getStartDate() { - return delegate.getStartDate(); - } - - @Override - public Date getCompleteDate() { - return delegate.getCompleteDate(); - } - - @Override - public KogitoNodeInstance getNodeInstance() { - return delegate.getNodeInstance(); - } - - @Override - public KogitoProcessInstance getProcessInstance() { - return delegate.getProcessInstance(); - } - - @Override - public String getName() { - return delegate.getName(); - } - - @Override - public int getState() { - return delegate.getState(); - } - - @Override - public Object getParameter(String name) { - return delegate.getParameter(name); - } - - @Override - public Map getParameters() { - return delegate.getParameters(); - } - - @Override - public Object getResult(String name) { - return delegate.getResult(name); - } - - @Override - public Map getResults() { - return delegate.getResults(); - } - - @Override - public String getProcessInstanceId() { - return delegate.getProcessInstanceId(); - } - - @Override - public String getNodeInstanceStringId() { - return delegate.getNodeInstanceStringId(); - } - - @Override - public String getDeploymentId() { - return delegate.getDeploymentId(); - } - - @Override - public long getNodeInstanceId() { - return delegate.getNodeInstanceId(); - } - - @Override - public WorkflowElementIdentifier getNodeId() { - return delegate.getNodeId(); - } - - // set data - @Override - public void setPhaseId(String phaseId) { - delegate.setPhaseId(phaseId); - } - - @Override - public void setProcessInstanceId(String processInstanceId) { - delegate.setProcessInstanceId(processInstanceId); - } - - @Override - public void setNodeInstanceId(String deploymentId) { - delegate.setNodeInstanceId(deploymentId); - } - - @Override - public void setPhaseStatus(String phaseStatus) { - String oldPhaseStatus = delegate.getPhaseStatus(); - delegate.setPhaseStatus(phaseStatus); - getEventSupport().ifPresent(e -> e.fireOneUserTaskStateChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), oldPhaseStatus, phaseStatus)); - - } - - @Override - public void setStartDate(Date date) { - delegate.setStartDate(date); - } - - @Override - public void setCompleteDate(Date date) { - delegate.setCompleteDate(date); - } - - @Override - public void setNodeInstance(KogitoNodeInstance nodeInstance) { - delegate.setNodeInstance(nodeInstance); - } - - @Override - public void setProcessInstance(KogitoProcessInstance processInstance) { - delegate.setProcessInstance(processInstance); - } - - @Override - public void setName(String name) { - delegate.setName(name); - } - - @Override - public void setParameter(String name, Object value) { - Object oldValue = delegate.getParameter(name); - delegate.setParameter(name, value); - getEventSupport().ifPresent(e -> e.fireOnUserTaskInputVariableChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), name, value, oldValue)); - } - - @Override - public void setParameters(Map parameters) { - parameters.forEach(this::setParameter); - } - - @Override - public void setResults(Map results) { - if (results != null) { - results.forEach(this::setResult); - } else { - Map outcome = new HashMap<>(delegate.getResults()); - delegate.setResults(null); - if (isActive()) { - for (String key : outcome.keySet()) { - getEventSupport().ifPresent(e -> e.fireOnUserTaskOutputVariableChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), key, null, outcome.get(key))); - } - } - } - } - - @Override - public void setResult(String name, Object value) { - Object oldValue = delegate.getParameter(name); - delegate.setResult(name, value); - if (isActive()) { - getEventSupport().ifPresent(e -> e.fireOnUserTaskOutputVariableChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), name, value, oldValue)); - } - } - - @Override - public void setState(int state) { - delegate.setState(state); - } - - @Override - public void setDeploymentId(String deploymentId) { - delegate.setDeploymentId(deploymentId); - } - - @Override - public void setNodeInstanceId(long deploymentId) { - delegate.setNodeInstanceId(deploymentId); - } - - @Override - public void setNodeId(WorkflowElementIdentifier nodeIdentifier) { - delegate.setNodeId(nodeIdentifier); - } - - @Override - public void setTaskName(String taskName) { - delegate.setTaskName(taskName); - - } - - @Override - public void setTaskDescription(String taskDescription) { - delegate.setTaskDescription(taskDescription); - if (delegate.getPhaseStatus() == null) { - return; - } - getEventSupport().ifPresent(e -> e.fireOneUserTaskStateChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), delegate.getPhaseStatus(), delegate.getPhaseStatus())); - } - - @Override - public void setTaskPriority(String taskPriority) { - delegate.setTaskPriority(taskPriority); - if (delegate.getPhaseStatus() == null) { - return; - } - getEventSupport().ifPresent(e -> e.fireOneUserTaskStateChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), delegate.getPhaseStatus(), delegate.getPhaseStatus())); - } - - @Override - public void setReferenceName(String referenceName) { - delegate.setReferenceName(referenceName); - } - - @Override - public void setActualOwner(String actualOwner) { - String currentPhaseStatus = delegate.getPhaseStatus(); - delegate.setActualOwner(actualOwner); - if (currentPhaseStatus == null) { - return; - } - getEventSupport().ifPresent(e -> e.fireOneUserTaskStateChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), currentPhaseStatus, currentPhaseStatus)); - } - - @Override - public void setPotentialUsers(Set potentialUsers) { - Set oldValue = new HashSet<>(delegate.getPotentialUsers()); - delegate.setPotentialUsers(potentialUsers); - getEventSupport().ifPresent(e -> e.fireOnUserTaskAssignmentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), AssignmentType.USER_OWNERS, oldValue, potentialUsers)); - } - - @Override - public void setPotentialGroups(Set potentialGroups) { - Set oldValue = new HashSet<>(delegate.getPotentialGroups()); - delegate.setPotentialGroups(potentialGroups); - getEventSupport().ifPresent(e -> e.fireOnUserTaskAssignmentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), AssignmentType.USER_GROUPS, oldValue, potentialGroups)); - } - - @Override - public void setAdminGroups(Set potentialAdmins) { - Set oldValue = new HashSet<>(delegate.getAdminGroups()); - delegate.setAdminGroups(potentialAdmins); - getEventSupport().ifPresent(e -> e.fireOnUserTaskAssignmentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), AssignmentType.ADMIN_GROUPS, oldValue, potentialAdmins)); - } - - @Override - public void setAdminUsers(Set adminUsers) { - Set oldValue = new HashSet<>(delegate.getAdminUsers()); - delegate.setAdminUsers(adminUsers); - getEventSupport().ifPresent(e -> e.fireOnUserTaskAssignmentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), AssignmentType.ADMIN_USERS, oldValue, adminUsers)); - - } - - @Override - public void setExcludedUsers(Set excludedUsers) { - Set oldValue = new HashSet<>(delegate.getExcludedUsers()); - delegate.setExcludedUsers(excludedUsers); - getEventSupport().ifPresent(e -> e.fireOnUserTaskAssignmentChange(getProcessInstance(), getNodeInstance(), getKieRuntime(), AssignmentType.USERS_EXCLUDED, oldValue, excludedUsers)); - } - - @Override - public boolean enforce(Policy... policies) { - return delegate.enforce(policies); - } - - @Override - public String toString() { - return delegate.toString(); - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemHandler.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemHandler.java deleted file mode 100644 index f1119ed6d8b..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask; - -import java.util.Map; -import java.util.stream.Stream; - -import org.jbpm.process.instance.impl.workitem.Abort; -import org.jbpm.process.instance.impl.workitem.Active; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.LifeCycle; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Transition; - -/** - * Work item handler to be used with human tasks (work items). - * It uses BaseHumanTaskLifeCycle by default but allows to plug in - * another life cycle implementation. - * - */ -public class HumanTaskWorkItemHandler implements KogitoWorkItemHandler { - - private final LifeCycle> lifeCycle; - - public HumanTaskWorkItemHandler() { - this(new BaseHumanTaskLifeCycle()); - } - - public HumanTaskWorkItemHandler(LifeCycle> lifeCycle) { - this.lifeCycle = lifeCycle; - } - - @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - lifeCycle.transitionTo(workItem, manager, new HumanTaskTransition(Active.ID)); - } - - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - lifeCycle.transitionTo(workItem, manager, new HumanTaskTransition(Abort.ID)); - } - - @Override - @SuppressWarnings("unchecked") - public void transitionToPhase(KogitoWorkItem workItem, KogitoWorkItemManager manager, Transition transition) { - lifeCycle.transitionTo(workItem, manager, (Transition>) transition); - } - - public static Stream allowedPhases(KogitoWorkItemHandler handler, String phaseId) { - if (handler instanceof HumanTaskWorkItemHandler) { - return ((HumanTaskWorkItemHandler) handler).lifeCycle.allowedPhases(phaseId); - } - return null; - } - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemImpl.java deleted file mode 100644 index 0679e9ba66e..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemImpl.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.kie.kogito.auth.IdentityProvider; -import org.kie.kogito.auth.SecurityPolicy; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class HumanTaskWorkItemImpl extends KogitoWorkItemImpl implements InternalHumanTaskWorkItem { - - private static final long serialVersionUID = 6168927742199190604L; - private static final Logger logger = LoggerFactory.getLogger(HumanTaskWorkItemImpl.class); - - private String taskName; - private String taskDescription; - private String taskPriority; - private String referenceName; - - private String actualOwner; - private Set potentialUsers = new HashSet<>(); - private Set potentialGroups = new HashSet<>(); - private Set excludedUsers = new HashSet<>(); - private Set adminUsers = new HashSet<>(); - private Set adminGroups = new HashSet<>(); - private Map comments = new ConcurrentHashMap<>(); - private Map attachments = new ConcurrentHashMap<>(); - - @Override - public String getTaskName() { - return taskName; - } - - public void setTaskName(String taskName) { - this.taskName = taskName; - } - - @Override - public String getTaskDescription() { - return taskDescription; - } - - public void setTaskDescription(String taskDescription) { - this.taskDescription = taskDescription; - } - - @Override - public String getTaskPriority() { - return taskPriority; - } - - public void setTaskPriority(String taskPriority) { - this.taskPriority = taskPriority; - } - - @Override - public String getReferenceName() { - return referenceName; - } - - public void setReferenceName(String referenceName) { - this.referenceName = referenceName; - } - - @Override - public String getActualOwner() { - return actualOwner; - } - - public void setActualOwner(String actualOwner) { - this.actualOwner = actualOwner; - } - - @Override - public Set getPotentialUsers() { - return potentialUsers; - } - - public void setPotentialUsers(Set potentialUsers) { - this.potentialUsers = potentialUsers; - } - - @Override - public Set getPotentialGroups() { - return potentialGroups; - } - - public void setPotentialGroups(Set potentialGroups) { - this.potentialGroups = potentialGroups; - } - - @Override - public Set getExcludedUsers() { - return excludedUsers; - } - - public void setExcludedUsers(Set excludedUsers) { - this.excludedUsers = excludedUsers; - } - - @Override - public Set getAdminUsers() { - return adminUsers; - } - - public void setAdminUsers(Set adminUsers) { - this.adminUsers = adminUsers; - } - - @Override - public Set getAdminGroups() { - return adminGroups; - } - - public void setAdminGroups(Set adminGroups) { - this.adminGroups = adminGroups; - } - - @Override - public boolean enforce(Policy... policies) { - for (Policy policy : policies) { - if (policy instanceof SecurityPolicy) { - try { - enforceAuthorization(((SecurityPolicy) policy).value()); - - return true; - } catch (NotAuthorizedException e) { - return false; - } - } - } - boolean authorized = true; - // there might have not been any policies given so let's ensure task is protected if any assignments is set - String currentOwner = getActualOwner(); - if ((currentOwner != null && !currentOwner.trim().isEmpty()) || !getPotentialUsers().isEmpty()) { - authorized = false; - } - - return authorized; - } - - protected void enforceAuthorization(IdentityProvider identity) { - - if (identity != null) { - logger.debug("Identity information provided, enforcing security restrictions, user '{}' with roles '{}'", identity.getName(), identity.getRoles()); - // in case identity/auth info is given enforce security restrictions - String user = identity.getName(); - String currentOwner = getActualOwner(); - // if actual owner is already set always enforce same user - if (currentOwner != null && !currentOwner.trim().isEmpty() && !user.equals(currentOwner) && - (getAdminUsers() == null || !getAdminUsers().contains(user))) { - logger.debug("Work item {} has already owner assigned so requesting user must match - owner '{}' == requestor '{}'", getStringId(), currentOwner, user); - throw new NotAuthorizedException("User " + user + " is not authorized to access task instance with id " + getStringId()); - } - - checkAssignedOwners(user, identity.getRoles()); - } - } - - protected void checkAssignedOwners(String user, Collection roles) { - // is not in the excluded users - if (getExcludedUsers().contains(user)) { - logger.debug("Requesting user '{}' is excluded from the potential workers on work item {}", user, getStringId()); - throw new NotAuthorizedException("User " + user + " is not authorized to access task instance with id " + getStringId()); - } - - // check if user is in potential users or groups - if (!getPotentialUsers().contains(user) && - getPotentialGroups().stream().noneMatch(roles::contains)) { - throw new NotAuthorizedException("User " + user + " is not authorized to access task instance with id " + getStringId()); - } - } - - @Override - public Map getAttachments() { - return attachments; - } - - @Override - public Map getComments() { - return comments; - } - - @Override - public void setAttachment(String id, Attachment attachment) { - attachments.put(id, attachment); - } - - @Override - public Attachment removeAttachment(String id) { - return attachments.remove(id); - } - - @Override - public void setComment(String id, Comment comment) { - comments.put(id, comment); - } - - @Override - public Comment removeComment(String id) { - return comments.remove(1); - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/InternalHumanTaskWorkItem.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/InternalHumanTaskWorkItem.java deleted file mode 100644 index 75180fd91a9..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/InternalHumanTaskWorkItem.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.jbpm.process.instance.impl.humantask; - -import java.util.Set; - -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitems.InternalKogitoWorkItem; - -public interface InternalHumanTaskWorkItem extends HumanTaskWorkItem, InternalKogitoWorkItem { - - void setTaskName(String parameter); - - void setTaskDescription(String parameter); - - void setTaskPriority(String parameter); - - void setReferenceName(String parameter); - - void setActualOwner(String string); - - void setPotentialUsers(Set potentialUsers); - - void setPotentialGroups(Set potentialGroups); - - void setAdminGroups(Set potentialGroups); - - void setAdminUsers(Set adminUsers); - - void setExcludedUsers(Set excludedUsers); - - void setAttachment(String id, Attachment attachment); - - void setComment(String id, Comment comment); - - Comment removeComment(String id); - - Attachment removeAttachment(String id); - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Claim.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Claim.java deleted file mode 100644 index 19a090ccdc4..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Claim.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask.phases; - -import java.util.Arrays; -import java.util.List; - -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.workitem.Active; -import org.kie.kogito.auth.SecurityPolicy; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; - -/** - * Claim life cycle phase that applies to human tasks. - * It will set the status to "Reserved" and assign actual owner if there is security - * context available. - * - * It can transition from - *
    - *
  • Active
  • - *
- */ -public class Claim implements LifeCyclePhase { - - public static final String ID = "claim"; - public static final String STATUS = "Reserved"; - - private List allowedTransitions = Arrays.asList(Active.ID, Release.ID); - - @Override - public String id() { - return ID; - } - - @Override - public String status() { - return STATUS; - } - - @Override - public boolean isTerminating() { - return false; - } - - @Override - public boolean canTransition(LifeCyclePhase phase) { - return allowedTransitions.contains(phase.id()); - } - - @Override - public void apply(KogitoWorkItem workitem, Transition transition) { - if (transition.policies() != null) { - for (Policy policy : transition.policies()) { - if (policy instanceof SecurityPolicy) { - ((InternalHumanTaskWorkItem) workitem).setActualOwner(((SecurityPolicy) policy).value().getName()); - break; - } - } - } - ((InternalHumanTaskWorkItem) workitem).setResult("ActorId", ((HumanTaskWorkItem) workitem).getActualOwner()); - } - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Release.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Release.java deleted file mode 100644 index 7919f00d41a..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Release.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask.phases; - -import java.util.Arrays; -import java.util.List; - -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Transition; - -/** - * Release life cycle phase that applies to human tasks. - * It will set the status to "Ready" and resets actual owner - * - * It can transition from - *
    - *
  • Claim
  • - *
- */ -public class Release implements LifeCyclePhase { - - public static final String ID = "release"; - public static final String STATUS = "Ready"; - - private List allowedTransitions = Arrays.asList(Claim.ID); - - @Override - public String id() { - return ID; - } - - @Override - public String status() { - return STATUS; - } - - @Override - public boolean isTerminating() { - return false; - } - - @Override - public boolean canTransition(LifeCyclePhase phase) { - return allowedTransitions.contains(phase.id()); - } - - @Override - public void apply(KogitoWorkItem workitem, Transition transition) { - ((InternalHumanTaskWorkItem) workitem).setActualOwner(null); - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Skip.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Skip.java deleted file mode 100644 index db5bd4d8285..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/phases/Skip.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.humantask.phases; - -import java.util.Arrays; -import java.util.List; - -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.workitem.Active; -import org.kie.kogito.auth.SecurityPolicy; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; - -/** - * Skip life cycle phase that applies to human tasks. - * It will set the status to "Skipped" - * - * It can transition from - *
    - *
  • Active
  • - *
  • Claim
  • - *
  • Release
  • - *
- * - * This is a terminating (final) phase. - */ -public class Skip implements LifeCyclePhase { - - public static final String ID = "skip"; - public static final String STATUS = "Skipped"; - - private List allowedTransitions = Arrays.asList(Active.ID, Claim.ID, Release.ID); - - @Override - public String id() { - return ID; - } - - @Override - public String status() { - return STATUS; - } - - @Override - public boolean isTerminating() { - return true; - } - - @Override - public boolean canTransition(LifeCyclePhase phase) { - return allowedTransitions.contains(phase.id()); - } - - @Override - public void apply(KogitoWorkItem workitem, Transition transition) { - if (transition.policies() != null) { - for (Policy policy : transition.policies()) { - if (policy instanceof SecurityPolicy) { - ((InternalHumanTaskWorkItem) workitem).setActualOwner(((SecurityPolicy) policy).value().getName()); - break; - } - } - } - ((InternalHumanTaskWorkItem) workitem).setResult("ActorId", ((HumanTaskWorkItem) workitem).getActualOwner()); - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Abort.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Abort.java deleted file mode 100644 index c9828bd79ad..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Abort.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.workitem; - -import java.util.Arrays; -import java.util.List; - -import org.jbpm.process.instance.impl.humantask.phases.Claim; -import org.jbpm.process.instance.impl.humantask.phases.Release; -import org.kie.kogito.process.workitem.LifeCyclePhase; - -/** - * Abort life cycle phase that applies to any work item. - * It will set the status to "Aborted" - * - * It can transition from - *
    - *
  • Active
  • - *
  • Claim
  • - *
  • Release
  • - *
- * - */ -public class Abort implements LifeCyclePhase { - - public static final String ID = "abort"; - public static final String STATUS = "Aborted"; - - private List allowedTransitions = Arrays.asList(Active.ID, Claim.ID, Release.ID); - - @Override - public String id() { - return ID; - } - - @Override - public String status() { - return STATUS; - } - - @Override - public boolean isTerminating() { - return false; - } - - @Override - public boolean canTransition(LifeCyclePhase phase) { - return allowedTransitions.contains(phase.id()); - } - -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Complete.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Complete.java deleted file mode 100644 index 23478e6346b..00000000000 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Complete.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jbpm.process.instance.impl.workitem; - -import java.util.Arrays; -import java.util.List; - -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.humantask.phases.Claim; -import org.jbpm.process.instance.impl.humantask.phases.Release; -import org.kie.kogito.auth.SecurityPolicy; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; - -/** - * Complete life cycle phase that applies to any human task. - * It will set the status to "Completed" - * - * It can transition from - *
    - *
  • Active
  • - *
  • Claim
  • - *
  • Release
  • - *
- * - * This is a terminating (final) phase. - */ -public class Complete implements LifeCyclePhase { - - public static final String ID = "complete"; - public static final String STATUS = "Completed"; - - private List allowedTransitions = Arrays.asList(Active.ID, Claim.ID, Release.ID); - - @Override - public String id() { - return ID; - } - - @Override - public String status() { - return STATUS; - } - - @Override - public boolean isTerminating() { - return true; - } - - @Override - public boolean canTransition(LifeCyclePhase phase) { - return allowedTransitions.contains(phase.id()); - } - - @Override - public void apply(KogitoWorkItem workitem, Transition transition) { - if (workitem instanceof HumanTaskWorkItem) { - if (transition.policies() != null) { - for (Policy policy : transition.policies()) { - if (policy instanceof SecurityPolicy) { - ((InternalHumanTaskWorkItem) workitem).setActualOwner(((SecurityPolicy) policy).value().getName()); - break; - } - } - } - ((InternalHumanTaskWorkItem) workitem).setResult("ActorId", ((HumanTaskWorkItem) workitem).getActualOwner()); - } - } -} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/util/ContextFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/util/ContextFactory.java index 6d73e371b6e..a2087a520b2 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/util/ContextFactory.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/util/ContextFactory.java @@ -21,7 +21,7 @@ import org.jbpm.process.instance.KogitoProcessContextImpl; import org.jbpm.process.instance.ProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; public class ContextFactory { diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/util/JsonSchemaUtil.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/util/JsonSchemaUtil.java index 2ba82c8f885..f280aaa714d 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/util/JsonSchemaUtil.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/util/JsonSchemaUtil.java @@ -23,16 +23,13 @@ import java.nio.file.Path; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.Policy; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.ProcessInstanceReadMode; import org.kie.kogito.process.WorkItem; -import org.kie.kogito.process.workitem.LifeCyclePhase; -import org.kie.kogito.process.workitem.Policy; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -90,23 +87,16 @@ public static Map addPhases(Process process, KogitoWorkItemHandler workItemHandler, String processInstanceId, String workItemId, - Policy[] policies, + Policy[] policies, Map jsonSchema) { return process.instances().findById(processInstanceId, ProcessInstanceReadMode.READ_ONLY).map(pi -> { - jsonSchema - .put( - "phases", - allowedPhases( - workItemHandler, - pi.workItem(workItemId, policies))); + WorkItem workItem = pi.workItem(workItemId, policies); + Set transitions = workItemHandler.allowedTransitions(workItem.getPhaseStatus()); + jsonSchema.put("phases", transitions); return jsonSchema; }).orElseThrow(() -> new ProcessInstanceNotFoundException(processInstanceId)); } - public static Set allowedPhases(KogitoWorkItemHandler handler, WorkItem workItem) { - return HumanTaskWorkItemHandler.allowedPhases(handler, workItem.getPhase()).map(LifeCyclePhase::id).collect(Collectors.toSet()); - } - public static String pathFor(String key) { return jsonDir + getFileName(key); } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/DataAssociation.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/DataAssociation.java index 468115c508b..b635f3c23ef 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/DataAssociation.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/DataAssociation.java @@ -65,7 +65,12 @@ public void setType(DataAssociationType type) { private Assignment buildInterpretedAssignment(Assignment assignment) { if (assignment.getDialect() != null) { - return assignment; + if (assignment.getDialect().toLowerCase().equals("xpath")) { + assignment.setMetaData("Action", new XPATHAssignmentAction(assignment, sources, target)); + return assignment; + } else { + return assignment; + } } if (isExpr(assignment.getFrom().getExpression())) { assignment.setMetaData("Action", new InputExpressionAssignment(assignment.getFrom(), assignment.getTo())); diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentAction.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/XPATHAssignmentAction.java similarity index 59% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentAction.java rename to jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/XPATHAssignmentAction.java index 01005a1b3f3..c3b2383dd98 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xpath/XPATHAssignmentAction.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/XPATHAssignmentAction.java @@ -16,13 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.xpath; +package org.jbpm.workflow.core.impl; +import java.io.ByteArrayInputStream; +import java.io.StringWriter; import java.util.List; import java.util.function.Function; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; @@ -30,13 +36,11 @@ import org.jbpm.process.instance.impl.AssignmentAction; import org.jbpm.process.instance.impl.AssignmentProducer; -import org.jbpm.workflow.core.impl.DataDefinition; import org.jbpm.workflow.core.node.Assignment; import org.w3c.dom.Attr; -import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.NodeList; import org.w3c.dom.Text; +import org.xml.sax.InputSource; public class XPATHAssignmentAction implements AssignmentAction { @@ -53,80 +57,67 @@ public XPATHAssignmentAction(Assignment assignment, public void execute(Function sourceResolver, Function targetResolver, AssignmentProducer producer) throws Exception { - String from = assignment.getFrom().getExpression(); - String to = assignment.getTo().getExpression(); - XPathFactory factory = XPathFactory.newInstance(); - XPath xpathFrom = factory.newXPath(); - XPathExpression exprFrom = xpathFrom.compile(from); + String from = assignment.getFrom().getExpression(); + XPath xpathFrom = factory.newXPath(); + XPathExpression exprFrom = null; XPath xpathTo = factory.newXPath(); - + String to = assignment.getTo().getExpression(); XPathExpression exprTo = xpathTo.compile(to); Object target = null; Object source = null; if (!sourcesDefinitions.isEmpty()) { + // it means there is not expression (it is constant) source = sourceResolver.apply(sourcesDefinitions.get(0).getLabel()); + exprFrom = xpathFrom.compile(from); } else { source = assignment.getFrom().getExpression(); + exprFrom = xpathFrom.compile("."); } target = targetResolver.apply(targetDefinition.getLabel()); - Object targetElem = null; - - // now pick the leaf for this operation - if (target != null) { - org.w3c.dom.Node parent; - parent = ((org.w3c.dom.Node) target).getParentNode(); - - targetElem = exprTo.evaluate(parent, XPathConstants.NODE); - - if (targetElem == null) { - throw new RuntimeException("Nothing was selected by the to expression " + to + " on " + target); - } - } - NodeList nl = null; + // calculate node source. The outcome is Node type + org.w3c.dom.Node sourceDOM = null; if (source instanceof org.w3c.dom.Node) { - nl = (NodeList) exprFrom.evaluate(source, XPathConstants.NODESET); - } else if (source instanceof String) { + sourceDOM = (org.w3c.dom.Node) exprFrom.evaluate(source, XPathConstants.NODE); + } else if (source instanceof String sourceString) { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document doc = builder.newDocument(); - //quirky: create a temporary element, use its nodelist - Element temp = doc.createElementNS(null, "temp"); - temp.appendChild(doc.createTextNode((String) source)); - nl = temp.getChildNodes(); - } else if (source == null) { - // don't throw errors yet ? - throw new RuntimeException("Source value was null for source " + source); + sourceDOM = builder.parse(new InputSource(new ByteArrayInputStream(sourceString.getBytes()))).getFirstChild(); } - if (nl == null || nl.getLength() == 0) { + if (sourceDOM == null) { throw new RuntimeException("Nothing was selected by the from expression " + from + " on " + source); } - for (int i = 0; i < nl.getLength(); i++) { - - if (!(targetElem instanceof org.w3c.dom.Node)) { - if (nl.item(i) instanceof Attr) { - targetElem = ((Attr) nl.item(i)).getValue(); - } else if (nl.item(i) instanceof Text) { - targetElem = ((Text) nl.item(i)).getWholeText(); - } else { - DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document doc = builder.newDocument(); - targetElem = doc.importNode(nl.item(i), true); - } - target = targetElem; + + // now compute the target either there is a parent node node or there is not + if (target instanceof org.w3c.dom.Node parentNode) { + org.w3c.dom.Node parent = parentNode.getParentNode(); + org.w3c.dom.Node targetElem = (org.w3c.dom.Node) exprTo.evaluate(parent, XPathConstants.NODE); + if (targetElem == null) { + throw new RuntimeException("Nothing was selected by the to expression " + to + " on " + target); + } + org.w3c.dom.Node n = targetElem.getOwnerDocument().importNode(sourceDOM, true); + if (n instanceof Attr attr) { + ((Element) targetElem).setAttributeNode(attr); } else { - org.w3c.dom.Node n = ((org.w3c.dom.Node) targetElem).getOwnerDocument().importNode(nl.item(i), true); - if (n instanceof Attr) { - ((Element) targetElem).setAttributeNode((Attr) n); - } else { - ((org.w3c.dom.Node) targetElem).appendChild(n); - } + (targetElem).appendChild(n); } + target = targetElem; + } else if (org.w3c.dom.Node.class.getName().equals(targetDefinition.getType())) { + target = sourceDOM; + } else if (sourceDOM instanceof Attr) { + target = ((Attr) sourceDOM).getValue(); + } else if (sourceDOM instanceof Text) { + target = ((Text) sourceDOM).getWholeText(); + } else { + StringWriter writer = new StringWriter(); + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform(new DOMSource(sourceDOM), new StreamResult(writer)); + target = writer.toString(); } producer.accept(targetDefinition.getLabel(), target); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java index c604312a8cf..79ef9e1d070 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java @@ -52,6 +52,7 @@ import org.jbpm.process.instance.context.variable.VariableScopeInstance; import org.jbpm.process.instance.impl.ProcessInstanceImpl; import org.jbpm.ruleflow.core.Metadata; +import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory; import org.jbpm.util.PatternConstants; import org.jbpm.workflow.core.DroolsAction; import org.jbpm.workflow.core.Node; @@ -679,11 +680,16 @@ public void signalEvent(String type, Object event) { } } for (org.kie.api.definition.process.Node node : getWorkflowProcess().getNodes()) { - if (node instanceof EventNodeInterface - && ((EventNodeInterface) node).acceptsEvent(type, event, getResolver(node, currentView))) { - if (node instanceof EventNode && ((EventNode) node).getFrom() == null) { - EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node); - eventNodeInstance.signalEvent(type, event, getResolver(node, currentView)); + if (node instanceof EventNodeInterface && ((EventNodeInterface) node).acceptsEvent(type, event, getResolver(node, currentView))) { + if (node instanceof BoundaryEventNode boundaryEventNode) { + WorkflowElementIdentifier id = WorkflowElementIdentifierFactory.fromExternalFormat(boundaryEventNode.getAttachedToNodeId()); + if (!getNodeInstances(id, currentView).isEmpty()) { + EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node); + eventNodeInstance.signalEvent(type, event, getResolver(node, currentView)); + } else if (type.startsWith("Error-") || type.startsWith("Compensation-") || type.startsWith("implicit:compensation")) { + EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node); + eventNodeInstance.signalEvent(type, event, getResolver(node, currentView)); + } } else { if (node instanceof EventSubProcessNode && (resolveVariables(((EventSubProcessNode) node).getEvents()).contains(type))) { EventSubProcessNodeInstance eventNodeInstance = (EventSubProcessNodeInstance) getNodeInstance(node); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java index 0decee69f72..e4fbc359594 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java @@ -27,13 +27,17 @@ import org.jbpm.workflow.instance.NodeInstance; import org.jbpm.workflow.instance.NodeInstanceContainer; import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class BoundaryEventNodeInstance extends EventNodeInstance { + private static final Logger LOG = LoggerFactory.getLogger(BoundaryEventNodeInstance.class); private static final long serialVersionUID = -4958054074031174180L; @Override public void signalEvent(String type, Object event, Function varResolver) { + LOG.debug("Received boundary event signal {} and paydload {}", type, event); if (triggerTime == null) { triggerTime = new Date(); } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/DynamicUtils.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/DynamicUtils.java index 5c11434bf91..73ad2ace01b 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/DynamicUtils.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/DynamicUtils.java @@ -51,7 +51,7 @@ import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; import org.slf4j.Logger; @@ -98,6 +98,7 @@ private static KogitoWorkItem internalAddDynamicWorkItem( workItem.setId(UUID.randomUUID().toString()); workItem.setState(WorkItem.ACTIVE); workItem.setProcessInstanceId(processInstance.getStringId()); + workItem.setProcessInstance(processInstance); workItem.setDeploymentId((String) ksession.getEnvironment().get(EnvironmentName.DEPLOYMENT_ID)); workItem.setName(workItemName); workItem.setParameters(parameters); @@ -131,6 +132,7 @@ private static KogitoWorkItem internalAddDynamicWorkItem( } final WorkItemNodeInstance workItemNodeInstance = new WorkItemNodeInstance(); + workItemNodeInstance.setProcessInstance(processInstance); workItemNodeInstance.internalSetWorkItem(workItem); workItemNodeInstance.setMetaData("NodeType", workItemName); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/HumanTaskNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/HumanTaskNodeInstance.java index 3c1bc2a3415..3dfd858dcb4 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/HumanTaskNodeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/HumanTaskNodeInstance.java @@ -18,36 +18,13 @@ */ package org.jbpm.workflow.instance.node; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; -import org.jbpm.process.core.Work; import org.jbpm.process.core.context.swimlane.SwimlaneContext; -import org.jbpm.process.instance.InternalProcessRuntime; -import org.jbpm.process.instance.ProcessInstance; import org.jbpm.process.instance.context.swimlane.SwimlaneContextInstance; -import org.jbpm.process.instance.impl.humantask.DeadlineHelper; -import org.jbpm.process.instance.impl.humantask.DeadlineInfo; -import org.jbpm.process.instance.impl.humantask.HumanTaskHelper; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemImpl; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.humantask.Reassignment; -import org.jbpm.process.instance.impl.humantask.ScheduleInfo; import org.jbpm.workflow.core.node.HumanTaskNode; import org.jbpm.workflow.core.node.WorkItemNode; -import org.kie.kogito.internal.process.event.KogitoProcessEventSupport; -import org.kie.kogito.jobs.JobsService; -import org.kie.kogito.jobs.ProcessInstanceJobDescription; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; -import org.kie.kogito.timer.TimerInstance; - -import static org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT; public class HumanTaskNodeInstance extends WorkItemNodeInstance { @@ -58,6 +35,7 @@ public class HumanTaskNodeInstance extends WorkItemNodeInstance { private static final String TASK_NAME = "TaskName"; private String separator = System.getProperty("org.jbpm.ht.user.separator", ","); + private static final String ACTUAL_OWNER = "ActualOwner"; private static final String ACTOR_ID = "ActorId"; private static final String GROUP_ID = "GroupId"; private static final String BUSINESSADMINISTRATOR_ID = "BusinessAdministratorId"; @@ -67,151 +45,20 @@ public class HumanTaskNodeInstance extends WorkItemNodeInstance { private transient SwimlaneContextInstance swimlaneContextInstance; - private Map> notStartedDeadlines = new ConcurrentHashMap<>(); - private Map> notCompletedDeadlines = new ConcurrentHashMap<>(); - private Map notStartedReassignments = new ConcurrentHashMap<>(); - private Map notCompletedReassignments = new ConcurrentHashMap<>(); - public HumanTaskNode getHumanTaskNode() { return (HumanTaskNode) getNode(); } - @Override - public InternalHumanTaskWorkItem getWorkItem() { - return (InternalHumanTaskWorkItem) super.getWorkItem(); - } - - protected InternalKogitoWorkItem decorate(InternalKogitoWorkItem kogitoWorkItem) { - this.getKogitoProcessInstance(); - return HumanTaskHelper.decorate(this, (InternalHumanTaskWorkItem) kogitoWorkItem); - } - - @Override - protected InternalKogitoWorkItem newWorkItem() { - return HumanTaskHelper.decorate(this, new HumanTaskWorkItemImpl()); - } - - /* - * Since job service just communicate the timer id to listeners, we need to keep - * a map between the timer id and the notification information for not started task deadlines - * (which consist of a list of key value pairs) - */ - public Map> getNotStartedDeadlineTimers() { - return notStartedDeadlines; - } - - /* - * Since job service just communicate the timer id to listeners, we need to keep - * a map between the timer id and the notification information for not completed task deadlines - * (which consist of a list of key value pairs) - */ - public Map> getNotCompletedDeadlineTimers() { - return notCompletedDeadlines; - } - - public Map getNotStartedReassignments() { - return notStartedReassignments; - } - - public Map getNotCompletedReassigments() { - return notCompletedReassignments; - } - @Override protected InternalKogitoWorkItem createWorkItem(WorkItemNode workItemNode) { - InternalHumanTaskWorkItem workItem = (InternalHumanTaskWorkItem) super.createWorkItem(workItemNode); + InternalKogitoWorkItem workItem = super.createWorkItem(workItemNode); String actorId = assignWorkItem(workItem); if (actorId != null) { workItem.setParameter(ACTOR_ID, actorId); } - - workItem.setTaskName((String) workItem.getParameter(TASK_NAME)); - workItem.setTaskDescription((String) workItem.getParameter(DESCRIPTION)); - workItem.setTaskPriority((String) workItem.getParameter(PRIORITY)); - workItem.setReferenceName((String) workItem.getParameter(NODE_NAME)); - Work work = workItemNode.getWork(); - scheduleDeadlines(work.getNotStartedDeadlines(), notStartedDeadlines); - scheduleDeadlines(work.getNotCompletedDeadlines(), notCompletedDeadlines); - scheduleDeadlines(work.getNotStartedReassignments(), notStartedReassignments); - scheduleDeadlines(work.getNotCompletedReassigments(), notCompletedReassignments); return workItem; } - private void scheduleDeadlines(Collection> deadlines, - Map timers) { - if (!deadlines.isEmpty()) { - ProcessInstance pi = getProcessInstance(); - for (DeadlineInfo deadline : deadlines) { - for (ScheduleInfo info : deadline.getScheduleInfo()) { - timers.put(getJobsService().scheduleProcessInstanceJob(ProcessInstanceJobDescription.builder() - .generateId() - .timerId("-1") - .expirationTime(DeadlineHelper.getExpirationTime(info)) - .processInstanceId(pi.getStringId()) - .rootProcessInstanceId(pi.getRootProcessInstanceId()) - .processId(pi.getProcessId()) - .rootProcessId(pi.getRootProcessId()) - .nodeInstanceId(getStringId()).build()), deadline.getNotification()); - } - } - } - } - - @Override - public void signalEvent(String type, Object event) { - switch (type) { - case WORK_ITEM_TRANSITION: - cancelTimers(notStartedDeadlines); - cancelTimers(notStartedReassignments); - break; - case TIMER_TRIGGERED_EVENT: - if (!sendNotification((TimerInstance) event)) { - super.signalEvent(type, event); - } - break; - default: - super.signalEvent(type, event); - } - } - - private boolean sendNotification(TimerInstance timerInstance) { - boolean processed = checkAndSendNotitication(notStartedDeadlines, timerInstance, this::startNotification); - if (!processed) { - processed = checkAndSendNotitication(notCompletedDeadlines, timerInstance, this::endNotification); - } - if (!processed) { - processed = checkAndReassign(notStartedReassignments, timerInstance); - } - if (!processed) { - processed = checkAndReassign(notCompletedReassignments, timerInstance); - } - return processed; - } - - private boolean checkAndSendNotitication(Map> timers, - TimerInstance timerInstance, - Consumer> publisher) { - Map notification = timers.get(timerInstance.getId()); - boolean result = notification != null; - if (result) { - if (timerInstance.getRepeatLimit() <= 0) { - timers.remove(timerInstance.getId()); - } - publisher.accept(notification); - } - return result; - } - - private boolean checkAndReassign(Map timers, - TimerInstance timerInstance) { - Reassignment reassignment = timers.remove(timerInstance.getId()); - boolean result = reassignment != null; - if (result) { - reassign(reassignment); - } - return result; - } - @Override protected void addWorkItemListener() { super.addWorkItemListener(); @@ -224,43 +71,6 @@ protected void removeWorkItemListener() { getProcessInstance().removeEventListener(WORK_ITEM_TRANSITION, this, false); } - private KogitoProcessEventSupport getEventSupport() { - return InternalProcessRuntime.asKogitoProcessRuntime(getProcessInstance().getKnowledgeRuntime() - .getProcessRuntime()).getProcessEventSupport(); - } - - private JobsService getJobsService() { - return InternalProcessRuntime.asKogitoProcessRuntime(getProcessInstance().getKnowledgeRuntime() - .getProcessRuntime()).getJobsService(); - } - - private void startNotification(Map notification) { - getEventSupport().fireOnUserTaskNotStartedDeadline(getProcessInstance(), this, (HumanTaskWorkItem) getWorkItem(), - notification, getProcessInstance().getKnowledgeRuntime()); - } - - private void endNotification(Map notification) { - getEventSupport().fireOnUserTaskNotCompletedDeadline(getProcessInstance(), this, (HumanTaskWorkItem) getWorkItem(), - notification, - getProcessInstance().getKnowledgeRuntime()); - } - - private void reassign(Reassignment reassignment) { - InternalHumanTaskWorkItem humanTask = HumanTaskHelper.asHumanTask(getWorkItem()); - boolean modified = false; - if (!reassignment.getPotentialUsers().isEmpty()) { - humanTask.setPotentialUsers(reassignment.getPotentialUsers()); - modified = true; - } - if (!reassignment.getPotentialGroups().isEmpty()) { - humanTask.setPotentialGroups(reassignment.getPotentialGroups()); - modified = true; - } - if (modified) { - getEventSupport().fireAfterWorkItemTransition(getProcessInstance(), humanTask, null, null); - } - } - protected String assignWorkItem(InternalKogitoWorkItem workItem) { String actorId = null; // if this human task node is part of a swimlane, check whether an actor @@ -281,28 +91,6 @@ protected String assignWorkItem(InternalKogitoWorkItem workItem) { } } - InternalHumanTaskWorkItem hunanWorkItem = (InternalHumanTaskWorkItem) workItem; - - Set newPUValue = new HashSet<>(hunanWorkItem.getPotentialUsers()); - processAssigment(ACTOR_ID, workItem, newPUValue); - hunanWorkItem.setPotentialUsers(newPUValue); - - Set newPGValue = new HashSet<>(hunanWorkItem.getPotentialGroups()); - processAssigment(GROUP_ID, workItem, newPGValue); - hunanWorkItem.setPotentialGroups(newPGValue); - - Set newEUValue = new HashSet<>(hunanWorkItem.getExcludedUsers()); - processAssigment(EXCLUDED_OWNER_ID, workItem, newEUValue); - hunanWorkItem.setExcludedUsers(newEUValue); - - Set newAUValue = new HashSet<>(hunanWorkItem.getAdminUsers()); - processAssigment(BUSINESSADMINISTRATOR_ID, workItem, newAUValue); - hunanWorkItem.setAdminGroups(newAUValue); - - Set newAGValue = new HashSet<>(hunanWorkItem.getAdminGroups()); - processAssigment(BUSINESSADMINISTRATOR_GROUP_ID, workItem, newAGValue); - hunanWorkItem.setAdminGroups(newAGValue); - // always return ActorId from workitem as SwimlaneActorId is kept as separate parameter return (String) workItem.getParameter(ACTOR_ID); } @@ -326,14 +114,10 @@ private SwimlaneContextInstance getSwimlaneContextInstance(String swimlaneName) @Override public void triggerCompleted(InternalKogitoWorkItem workItem) { - cancelTimers(notStartedDeadlines); - cancelTimers(notCompletedDeadlines); - cancelTimers(notStartedReassignments); - cancelTimers(notCompletedReassignments); String swimlaneName = getHumanTaskNode().getSwimlane(); SwimlaneContextInstance swimlaneContextInstance = getSwimlaneContextInstance(swimlaneName); if (swimlaneContextInstance != null) { - String newActorId = (workItem instanceof HumanTaskWorkItem) ? ((HumanTaskWorkItem) workItem).getActualOwner() : (String) workItem.getParameter(ACTOR_ID); + String newActorId = (String) workItem.getParameter(ACTOR_ID); if (newActorId != null) { swimlaneContextInstance.setActorId(swimlaneName, newActorId); } @@ -341,14 +125,6 @@ public void triggerCompleted(InternalKogitoWorkItem workItem) { super.triggerCompleted(workItem); } - private void cancelTimers(Map timers) { - Iterator iter = timers.keySet().iterator(); - while (iter.hasNext()) { - getJobsService().cancelJob(iter.next()); - iter.remove(); - } - } - protected void processAssigment(String type, InternalKogitoWorkItem workItem, Set store) { String value = (String) workItem.getParameter(type); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java index c095d861bc7..054ef0ef8de 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java @@ -34,12 +34,12 @@ import org.jbpm.workflow.core.node.TimerNode; import org.kie.api.runtime.process.EventListener; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; import org.kie.kogito.jobs.ExpirationTime; import org.kie.kogito.jobs.JobsService; import org.kie.kogito.jobs.ProcessInstanceJobDescription; import org.kie.kogito.process.BaseEventDescription; import org.kie.kogito.process.EventDescription; -import org.kie.kogito.process.workitem.WorkItemExecutionException; import org.kie.kogito.services.uow.BaseWorkUnit; import org.kie.kogito.timer.TimerInstance; import org.kie.kogito.uow.WorkUnit; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java index 8f4dc4df820..5af0a5de03c 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java @@ -57,6 +57,7 @@ import org.kie.api.runtime.KieRuntime; import org.kie.api.runtime.process.EventListener; import org.kie.api.runtime.process.ProcessWorkItemHandlerException; +import org.kie.api.runtime.process.WorkItem; import org.kie.kogito.Model; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; @@ -75,6 +76,7 @@ import static org.jbpm.process.core.context.variable.VariableScope.VARIABLE_SCOPE; import static org.kie.api.runtime.process.WorkItem.ABORTED; +import static org.kie.api.runtime.process.WorkItem.ACTIVE; import static org.kie.api.runtime.process.WorkItem.COMPLETED; import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_ABORTED; import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_COMPLETED; @@ -105,15 +107,11 @@ protected WorkItemNode getWorkItemNode() { @Override public InternalKogitoWorkItem getWorkItem() { if (workItem == null && workItemId != null) { - workItem = decorate(((InternalKogitoWorkItemManager) getProcessInstance().getKnowledgeRuntime().getWorkItemManager()).getWorkItem(workItemId)); + workItem = ((InternalKogitoWorkItemManager) getProcessInstance().getKnowledgeRuntime().getWorkItemManager()).getWorkItem(workItemId); } return workItem; } - protected InternalKogitoWorkItem decorate(InternalKogitoWorkItem kogitoWorkItem) { - return kogitoWorkItem; - } - public String getWorkItemId() { return workItemId; } @@ -123,7 +121,7 @@ public void internalSetWorkItemId(String workItemId) { } public void internalSetWorkItem(InternalKogitoWorkItem workItem) { - this.workItem = decorate(workItem); + this.workItem = workItem; this.workItem.setProcessInstance(getProcessInstance()); this.workItem.setNodeInstance(this); } @@ -212,6 +210,8 @@ private ExceptionScopeInstance getExceptionScopeInstance(Object context, Excepti } // workItemId must be set otherwise cancel activity will not find the right work item this.workItemId = workItem.getStringId(); + Collection strings = exceptionScopeInstance.getExceptionScope().getExceptionHandlers().keySet(); + logger.info("exception scope {} with exception handlers {}", context, strings, e); return exceptionScopeInstance; } @@ -229,6 +229,7 @@ protected InternalKogitoWorkItem createWorkItem(WorkItemNode workItemNode) { workItem.setNodeInstance(this); workItem.setNodeInstanceId(this.getId()); workItem.setStartDate(new Date()); + workItem.setState(ACTIVE); Map resolvedParameters = new HashMap<>(); @@ -272,7 +273,11 @@ public void triggerCompleted(InternalKogitoWorkItem workItem) { if (workItemNode != null && workItem.getState() == COMPLETED) { validateWorkItemResultVariable(getProcessInstance().getProcessName(), workItemNode.getOutAssociations(), workItem); - NodeIoHelper.processOutputs(this, varRef -> workItem.getResult(varRef), varName -> this.getVariable(varName)); + Map outputs = new HashMap<>(workItem.getResults()); + if (workItem.getActualOwner() != null) { + outputs.put("ActorId", workItem.getActualOwner()); + } + NodeIoHelper.processOutputs(this, varRef -> outputs.get(varRef), varName -> this.getVariable(varName)); } if (getNode() == null) { @@ -290,7 +295,7 @@ public void triggerCompleted(InternalKogitoWorkItem workItem) { @Override public void cancel(CancelType cancelType) { InternalKogitoWorkItem item = getWorkItem(); - if (item != null && item.getState() != COMPLETED && item.getState() != ABORTED) { + if (item != null && !List.of(COMPLETED, ABORTED).contains(item.getState())) { try { ((InternalKogitoWorkItemManager) getProcessInstance().getKnowledgeRuntime().getWorkItemManager()).internalAbortWorkItem(item.getStringId()); } catch (WorkItemHandlerNotFoundException wihnfe) { @@ -336,13 +341,14 @@ public void removeEventListeners() { @Override public void signalEvent(String type, Object event) { if ("workItemCompleted".equals(type)) { - workItemCompleted((InternalKogitoWorkItem) event); + InternalKogitoWorkItem item = (InternalKogitoWorkItem) event; + workItemCompleted(item); } else if ("workItemAborted".equals(type)) { - workItemAborted((InternalKogitoWorkItem) event); + InternalKogitoWorkItem item = (InternalKogitoWorkItem) event; + workItemAborted(item); } else if (("processInstanceCompleted:" + exceptionHandlingProcessInstanceId).equals(type)) { exceptionHandlingCompleted((WorkflowProcessInstance) event, null); } else if (type.equals("RuleFlow-Activate" + getProcessInstance().getProcessId() + "-" + getNode().getUniqueId())) { - trigger(null, Node.CONNECTION_DEFAULT_TYPE); } else { super.signalEvent(type, event); @@ -360,6 +366,7 @@ public String[] getEventTypes() { public void workItemAborted(InternalKogitoWorkItem workItem) { if (workItem.getStringId().equals(workItemId) || (workItemId == null && getWorkItem().getStringId().equals(workItem.getStringId()))) { + workItem.setState(WorkItem.ABORTED); removeEventListeners(); triggerCompleted(workItem); } @@ -367,6 +374,7 @@ public void workItemAborted(InternalKogitoWorkItem workItem) { public void workItemCompleted(InternalKogitoWorkItem workItem) { if (workItem.getStringId().equals(workItemId) || (workItemId == null && getWorkItem().getStringId().equals(workItem.getStringId()))) { + workItem.setState(WorkItem.COMPLETED); removeEventListeners(); triggerCompleted(workItem); } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java index 4c763d85931..96ec9a0e659 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.locks.Lock; @@ -48,8 +49,10 @@ import org.kie.kogito.internal.process.runtime.KogitoNode; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.internal.utils.ConversionUtils; import org.kie.kogito.jobs.DurationExpirationTime; import org.kie.kogito.jobs.ExactExpirationTime; @@ -63,6 +66,9 @@ import org.kie.kogito.process.ProcessInstancesFactory; import org.kie.kogito.process.ProcessVersionResolver; import org.kie.kogito.process.Signal; +import org.kie.kogito.process.WorkItem; + +import static org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory.findAllKogitoWorkItemHandlersRegistered; @SuppressWarnings("unchecked") public abstract class AbstractProcess implements Process, ProcessSupplier { @@ -84,16 +90,15 @@ public abstract class AbstractProcess implements Process, Pr private ProcessVersionResolver versionResolver; protected AbstractProcess() { - this(new LightProcessRuntimeServiceProvider()); + this(null, new LightProcessRuntimeServiceProvider()); } protected AbstractProcess(ProcessConfig config, Application application) { - this(new ConfiguredProcessServices(config)); - this.app = application; + this(application, new ConfiguredProcessServices(config)); } - protected AbstractProcess(ProcessRuntimeServiceProvider services) { - this(services, Collections.emptyList(), null, null, null); + protected AbstractProcess(Application application, ProcessRuntimeServiceProvider services) { + this(application, services, Collections.emptyList(), null, null, null); } protected AbstractProcess(Application app, Collection handlers, CorrelationService correlations) { @@ -101,20 +106,30 @@ protected AbstractProcess(Application app, Collection han } protected AbstractProcess(Application app, Collection handlers, CorrelationService correlations, ProcessInstancesFactory factory) { - this(new ConfiguredProcessServices(app.config().get(ProcessConfig.class)), handlers, correlations, factory, app.config().get(ProcessConfig.class).versionResolver()); - this.app = app; + this(app, new ConfiguredProcessServices(app.config().get(ProcessConfig.class)), handlers, correlations, factory, app.config().get(ProcessConfig.class).versionResolver()); + } - protected AbstractProcess(ProcessRuntimeServiceProvider services, Collection handlers, CorrelationService correlations, ProcessInstancesFactory factory, + protected AbstractProcess(Application app, ProcessRuntimeServiceProvider services, Collection handlers, CorrelationService correlations, ProcessInstancesFactory factory, ProcessVersionResolver versionResolver) { + this.app = app; this.services = services; this.instances = new MapProcessInstances<>(); this.processInstancesFactory = factory; this.correlations = Optional.ofNullable(correlations).orElseGet(() -> new DefaultCorrelationService()); this.versionResolver = Optional.ofNullable(versionResolver).orElse(p -> get().getVersion()); KogitoWorkItemManager workItemManager = services.getKogitoWorkItemManager(); - for (KogitoWorkItemHandler handler : handlers) { - workItemManager.registerWorkItemHandler(handler.getName(), handler); + + // loading defaults + Collection handlerIds = workItemManager.getHandlerIds(); + findAllKogitoWorkItemHandlersRegistered().stream().filter(e -> !handlerIds.contains(e.getName())).forEach(workItemHandler -> { + workItemHandler.setApplication(app); + workItemManager.registerWorkItemHandler(workItemHandler.getName(), workItemHandler); + }); + // overriding kogito work item handlers + for (KogitoWorkItemHandler workItemHandler : handlers) { + workItemHandler.setApplication(app); + workItemManager.registerWorkItemHandler(workItemHandler.getName(), workItemHandler); } } @@ -128,6 +143,17 @@ public String name() { return get().getName(); } + @Override + public WorkItemTransition newTransition(WorkItem workItem, String transitionId, Map map, Policy... policy) { + KogitoWorkItemHandler handler = getKogitoWorkItemHandler(workItem.getWorkItemHandlerName()); + return handler.newTransition(transitionId, workItem.getPhaseStatus(), map, policy); + } + + @Override + public KogitoWorkItemHandler getKogitoWorkItemHandler(String workItemHandlerName) { + return services.getKogitoWorkItemManager().getKogitoWorkItemHandler(workItemHandlerName); + } + @Override public String version() { return versionResolver.apply(this); 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 a035be6bf4e..39d29374656 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 @@ -19,7 +19,6 @@ package org.kie.kogito.process.impl; import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -34,6 +33,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Stream; import org.jbpm.process.instance.InternalProcessRuntime; import org.jbpm.ruleflow.core.RuleFlowProcess; @@ -55,8 +55,10 @@ import org.kie.kogito.internal.process.event.KogitoEventListener; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.EventDescription; import org.kie.kogito.process.MutableProcessInstances; import org.kie.kogito.process.NodeInstanceNotFoundException; @@ -69,8 +71,7 @@ import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.flexible.AdHocFragment; import org.kie.kogito.process.flexible.Milestone; -import org.kie.kogito.process.workitem.Policy; -import org.kie.kogito.process.workitem.Transition; +import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.services.uow.ProcessInstanceWorkUnit; public abstract class AbstractProcessInstance implements ProcessInstance { @@ -496,70 +497,84 @@ public Collection findNodes(Predicate pr } @Override - public WorkItem workItem(String workItemId, Policy... policies) { - WorkItemNodeInstance workItemInstance = (WorkItemNodeInstance) processInstance().getNodeInstances(true) - .stream() - .filter(ni -> ni instanceof WorkItemNodeInstance && ((WorkItemNodeInstance) ni).getWorkItemId().equals(workItemId) && ((WorkItemNodeInstance) ni).getWorkItem().enforce(policies)) - .findFirst() + public WorkItem workItem(String workItemId, Policy... policies) { + return processInstance().getNodeInstances(true).stream() + .filter(WorkItemNodeInstance.class::isInstance) + .map(WorkItemNodeInstance.class::cast) + .filter(w -> enforceException(w.getWorkItem(), policies)) + .filter(ni -> ni.getWorkItemId().equals(workItemId)) + .map(this::toBaseWorkItem) + .findAny() .orElseThrow(() -> new WorkItemNotFoundException("Work item with id " + workItemId + " was not found in process instance " + id(), workItemId)); - return new BaseWorkItem(workItemInstance.getStringId(), - workItemInstance.getWorkItem().getStringId(), - workItemInstance.getNode().getId(), - (String) workItemInstance.getWorkItem().getParameters().getOrDefault("TaskName", workItemInstance.getNodeName()), - workItemInstance.getWorkItem().getState(), - workItemInstance.getWorkItem().getPhaseId(), - workItemInstance.getWorkItem().getPhaseStatus(), - workItemInstance.getWorkItem().getParameters(), - workItemInstance.getWorkItem().getResults()); + } + + private boolean enforceException(KogitoWorkItem kogitoWorkItem, Policy... policies) { + Stream.of(policies).forEach(p -> p.enforce(kogitoWorkItem)); + return true; } @Override - public List workItems(Policy... policies) { + public List workItems(Policy... policies) { return workItems(WorkItemNodeInstance.class::isInstance, policies); } @Override - public List workItems(Predicate p, Policy... policies) { - List list = new ArrayList<>(); - for (NodeInstance ni : processInstance().getNodeInstances(true)) { - if (p.test(ni) && ((WorkItemNodeInstance) ni).getWorkItem().enforce(policies)) { - BaseWorkItem taskName = new BaseWorkItem(ni.getStringId(), - ((WorkItemNodeInstance) ni).getWorkItemId(), - ni.getNode().getId(), - (String) ((WorkItemNodeInstance) ni).getWorkItem().getParameters().getOrDefault("TaskName", ni.getNodeName()), - ((WorkItemNodeInstance) ni).getWorkItem().getState(), - ((WorkItemNodeInstance) ni).getWorkItem().getPhaseId(), - ((WorkItemNodeInstance) ni).getWorkItem().getPhaseStatus(), - ((WorkItemNodeInstance) ni).getWorkItem().getParameters(), - ((WorkItemNodeInstance) ni).getWorkItem().getResults()); - list.add(taskName); - } + public List workItems(Predicate p, Policy... policies) { + return processInstance().getNodeInstances(true).stream() + .filter(p::test) + .filter(WorkItemNodeInstance.class::isInstance) + .map(WorkItemNodeInstance.class::cast) + .filter(w -> enforce(w.getWorkItem(), policies)) + .map(this::toBaseWorkItem) + .toList(); + } + + private WorkItem toBaseWorkItem(WorkItemNodeInstance workItemNodeInstance) { + InternalKogitoWorkItem workItem = workItemNodeInstance.getWorkItem(); + return new BaseWorkItem( + workItemNodeInstance.getStringId(), + workItemNodeInstance.getWorkItemId(), + workItemNodeInstance.getNode().getId(), + (String) workItem.getParameters().getOrDefault("TaskName", workItemNodeInstance.getNodeName()), + workItem.getName(), + workItem.getState(), + workItem.getPhaseId(), + workItem.getPhaseStatus(), + workItem.getParameters(), + workItem.getResults(), + workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID) + ":" + workItem.getExternalReferenceId()); + } + + private boolean enforce(KogitoWorkItem kogitoWorkItem, Policy... policies) { + try { + Stream.of(policies).forEach(p -> p.enforce(kogitoWorkItem)); + return true; + } catch (Throwable th) { + return false; } - return list; } @Override - public void completeWorkItem(String id, Map variables, Policy... policies) { + public void completeWorkItem(String id, Map variables, Policy... policies) { getProcessRuntime().getKogitoProcessRuntime().getKogitoWorkItemManager().completeWorkItem(id, variables, policies); removeOnFinish(); } @Override - public R updateWorkItem(String id, Function updater, Policy... policies) { - R result = getProcessRuntime().getKogitoProcessRuntime().getKogitoWorkItemManager().updateWorkItem(id, updater, - policies); + public R updateWorkItem(String id, Function updater, Policy... policies) { + R result = getProcessRuntime().getKogitoProcessRuntime().getKogitoWorkItemManager().updateWorkItem(id, updater, policies); addToUnitOfWork(pi -> ((MutableProcessInstances) process.instances()).update(pi.id(), pi)); return result; } @Override - public void abortWorkItem(String id, Policy... policies) { + public void abortWorkItem(String id, Policy... policies) { getProcessRuntime().getKogitoProcessRuntime().getKogitoWorkItemManager().abortWorkItem(id, policies); removeOnFinish(); } @Override - public void transitionWorkItem(String id, Transition transition) { + public void transitionWorkItem(String id, WorkItemTransition transition) { getProcessRuntime().getKogitoProcessRuntime().getKogitoWorkItemManager().transitionWorkItem(id, transition); removeOnFinish(); } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java index 3b5d1f72ded..02e6292a742 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java @@ -36,19 +36,25 @@ public class BaseWorkItem implements WorkItem { private Map parameters; private Map results; + private String workItemHandlerName; + private String externalReferenceId; @SuppressWarnings("squid:S107") - public BaseWorkItem(String nodeInstanceId, String id, WorkflowElementIdentifier nodeId, String name, int state, String phase, String phaseStatus, Map parameters, - Map results) { + public BaseWorkItem(String nodeInstanceId, String id, WorkflowElementIdentifier nodeId, String name, String workItemHandlerName, int state, String phase, String phaseStatus, + Map parameters, + Map results, + String externalReferenceId) { this.id = id; this.nodeInstanceId = nodeInstanceId; this.nodeId = nodeId; this.name = name; + this.workItemHandlerName = workItemHandlerName; this.state = state; this.phase = phase; this.phaseStatus = phaseStatus; this.parameters = parameters; this.results = results; + this.externalReferenceId = externalReferenceId; } @Override @@ -101,4 +107,14 @@ public String toString() { return "WorkItem [id=" + id + ", name=" + name + ", state=" + state + ", phase=" + phase + ", phaseStatus=" + phaseStatus + "]"; } + @Override + public String getWorkItemHandlerName() { + return workItemHandlerName; + } + + @Override + public String getExternalReferenceId() { + return externalReferenceId; + } + } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/CachedWorkItemHandlerConfig.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/CachedWorkItemHandlerConfig.java index 7c97856fa6e..a23d2a03a99 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/CachedWorkItemHandlerConfig.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/CachedWorkItemHandlerConfig.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.NoSuchElementException; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.WorkItemHandlerConfig; public class CachedWorkItemHandlerConfig implements WorkItemHandlerConfig { diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/DefaultWorkItemHandlerConfig.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/DefaultWorkItemHandlerConfig.java index f8b865ed98b..7d96d52b63d 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/DefaultWorkItemHandlerConfig.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/DefaultWorkItemHandlerConfig.java @@ -18,12 +18,6 @@ */ package org.kie.kogito.process.impl; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler; - public class DefaultWorkItemHandlerConfig extends CachedWorkItemHandlerConfig { - { - register("Log", new SystemOutWorkItemHandler()); - register("Human Task", new HumanTaskWorkItemHandler()); - } + } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/MultiWorkItemHandlerConfig.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/MultiWorkItemHandlerConfig.java index c0ef7e69efd..730e8870359 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/MultiWorkItemHandlerConfig.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/MultiWorkItemHandlerConfig.java @@ -22,7 +22,7 @@ import java.util.HashSet; import java.util.NoSuchElementException; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.WorkItemHandlerConfig; public class MultiWorkItemHandlerConfig implements WorkItemHandlerConfig { diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java index 12620be4b29..57ad61d3639 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java @@ -19,19 +19,19 @@ package org.kie.kogito.process.impl; import java.util.Collection; -import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.UUID; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.jbpm.process.instance.impl.humantask.HumanTaskHelper; -import org.jbpm.process.instance.impl.humantask.HumanTaskTransition; import org.jbpm.util.JsonSchemaUtil; -import org.jbpm.workflow.core.node.HumanTaskNode; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; +import org.jbpm.workflow.core.node.WorkItemNode; +import org.jbpm.workflow.instance.node.WorkItemNodeInstance; import org.kie.kogito.Application; import org.kie.kogito.MapOutput; import org.kie.kogito.MappableToModel; @@ -40,18 +40,24 @@ import org.kie.kogito.config.ConfigBean; import org.kie.kogito.correlation.CompositeCorrelation; import org.kie.kogito.internal.process.runtime.KogitoNode; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; import org.kie.kogito.process.Process; -import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.ProcessInstanceReadMode; import org.kie.kogito.process.ProcessService; import org.kie.kogito.process.WorkItem; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.AttachmentInfo; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.Policy; import org.kie.kogito.services.uow.UnitOfWorkExecutor; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.UserTasks; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.AttachmentInfo; +import org.kie.kogito.usertask.model.Comment; + +import static java.util.Collections.emptyMap; public class ProcessServiceImpl implements ProcessService { @@ -163,77 +169,78 @@ public , R> Optional updatePartial(Process pr } @Override - public Optional> getTasks(Process process, String id, SecurityPolicy policy) { + public , R> Optional signalProcessInstance(Process process, String id, Object data, String signalName) { + return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), + () -> process.instances().findById(id) + .map(pi -> { + pi.send(Sig.of(signalName, data)); + return pi.checkError().variables().toModel(); + })); + } + + @Override + public Optional> getWorkItems(Process process, String id, Policy... policy) { return process.instances() .findById(id, ProcessInstanceReadMode.READ_ONLY) - .map(pi -> pi.workItems(HumanTaskNodeInstance.class::isInstance, policy)); + .map(pi -> pi.workItems(WorkItemNodeInstance.class::isInstance, policy)); } @Override - public Optional signalTask(Process process, String id, String taskName, SecurityPolicy policy) { - return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> { - KogitoNode node = pi.process().findNodes(n -> n instanceof HumanTaskNode && - ((HumanTaskNode) n).getWork().getParameter("TaskName") - .equals(taskName)) - .iterator().next(); - - String taskNodeName = node.getName(); - pi.send(Sig.of(taskNodeName, Collections.emptyMap())); - - return getTaskByName(pi, taskName, policy).orElse(null); - })); - } - - private Optional getTaskByName(ProcessInstance pi, String taskName, SecurityPolicy... policies) { - return pi - .workItems(policies) + public Optional signalWorkItem(Process process, String id, String taskNodeName, Policy... policy) { + return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> { + Optional> piFound = process.instances().findById(id); + if (piFound.isEmpty()) { + return Optional.empty(); + } + + ProcessInstance pi = piFound.get(); + return findWorkItem(pi, taskNodeName, policy); + }); + } + + private Optional findWorkItem(ProcessInstance pi, String taskName, Policy... policy) { + KogitoNode node = pi.process().findNodes(worktItemNodeNamed(taskName)).iterator().next(); + String taskNodeName = node.getName(); + pi.send(Sig.of(taskNodeName, emptyMap())); + return getWorkItemByTaskName(pi, taskName, policy); + } + + private Predicate worktItemNodeNamed(String taskName) { + return node -> node instanceof WorkItemNode workItemNode && taskName.equals(workItemNode.getWork().getParameter("TaskName")); + } + + private Optional getWorkItemByTaskName(ProcessInstance pi, String taskName, Policy... policies) { + return pi.workItems(policies) .stream() .filter(wi -> wi.getName().equals(taskName)) .findFirst(); } @Override - public Optional saveTask(Process process, - String id, - String taskId, - SecurityPolicy policy, - MapOutput model, - Function, R> mapper) { - return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem(taskId, wi -> HumanTaskHelper.updateContent(wi, model), policy))) - .map(mapper); - } - - @Override - public , R> Optional taskTransition( + public , R> Optional transitionWorkItem( Process process, - String id, - String taskId, - String phase, - SecurityPolicy policy, + String processInstanceId, + String workItemId, + String phaseId, + Policy policy, MapOutput model) { - HumanTaskTransition transition = - model == null ? HumanTaskTransition.withoutModel(phase, policy) - : HumanTaskTransition.withModel(phase, model, policy); - return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> { - pi.transitionWorkItem(taskId, transition); - return pi.variables().toModel(); - })); + + return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> { + return process.instances() + .findById(processInstanceId) + .map(pi -> { + WorkItem workItem = pi.workItem(workItemId, policy); + pi.transitionWorkItem(workItemId, process.newTransition(workItem, phaseId, model.toMap(), policy)); + return pi.variables().toModel(); + }); + }); } @Override - public , R> Optional getTask(Process process, + public , R> Optional getWorkItem(Process process, String id, String taskId, - SecurityPolicy policy, + Policy policy, Function mapper) { return process.instances() .findById(id, ProcessInstanceReadMode.READ_ONLY) @@ -241,20 +248,60 @@ public , R> Optional getTask(Process process, .map(mapper); } + @Override + public Optional setWorkItemOutput(Process process, + String id, + String taskId, + Policy policy, + MapOutput model, + Function, R> mapper) { + return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> { + return process.instances().findById(id) + .map(pi -> pi.updateWorkItem(taskId, wi -> { + wi.setOutputs(model.toMap()); + return model.toMap(); + }, policy)).map(mapper); + }); + } + + //Schema + @Override + public Map getWorkItemSchemaAndPhases(Process process, + String processInstanceId, + String workItemId, + String workItemTaskName, + Policy policy) { + // try to find work item handler + ProcessInstance pi = process.instances().findById(processInstanceId).orElseThrow(() -> new ProcessInstanceNotFoundException(processInstanceId)); + WorkItem workItem = pi.workItems(policy).stream() + .filter(wi -> wi.getId().equals(workItemId)) + .findFirst() + .orElseThrow(() -> new WorkItemNotFoundException(workItemId)); + KogitoWorkItemHandler handler = process.getKogitoWorkItemHandler(workItem.getWorkItemHandlerName()); + // we compute the phases + return JsonSchemaUtil.addPhases( + process, + handler, + processInstanceId, + workItemId, + new Policy[] { policy }, + JsonSchemaUtil.load(Thread.currentThread().getContextClassLoader(), process.id(), workItemTaskName)); + } + @Override public Optional addComment(Process process, String id, String taskId, SecurityPolicy policy, String commentInfo) { - return UnitOfWorkExecutor.executeInUnitOfWork( - application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem( - taskId, - wi -> HumanTaskHelper.addComment(wi, commentInfo, policy.value().getName()), - policy))); + return updateUserTaskInstance(process, id, taskId, policy, userTaskInstance -> { + Comment comment = new Comment(UUID.randomUUID().toString(), policy.getUser()); + comment.setContent(commentInfo); + comment.setUpdatedAt(new Date()); + userTaskInstance.addComment(comment); + return comment; + }); + } @Override @@ -264,14 +311,13 @@ public Optional updateComment(Process process, String commentId, SecurityPolicy policy, String commentInfo) { - return UnitOfWorkExecutor.executeInUnitOfWork( - application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem( - taskId, - wi -> HumanTaskHelper.updateComment(wi, commentId, commentInfo, policy.value().getName()), - policy))); + return updateUserTaskInstance(process, id, taskId, policy, userTaskInstance -> { + Comment comment = new Comment(commentId, policy.getUser()); + comment.setContent(commentInfo); + comment.setUpdatedAt(new Date()); + userTaskInstance.updateComment(comment); + return comment; + }); } @Override @@ -280,14 +326,13 @@ public Optional deleteComment(Process process, String taskId, String commentId, SecurityPolicy policy) { - return UnitOfWorkExecutor.executeInUnitOfWork( - application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem( - taskId, - wi -> HumanTaskHelper.deleteComment(wi, commentId, policy.value().getName()), - policy))); + return updateUserTaskInstance(process, id, taskId, policy, userTaskInstance -> { + Comment comment = new Comment(commentId, policy.getUser()); + comment.setContent(null); + comment.setUpdatedAt(new Date()); + userTaskInstance.removeComment(comment); + return Boolean.TRUE; + }); } @Override @@ -296,14 +341,14 @@ public Optional addAttachment(Process process, String taskId, SecurityPolicy policy, AttachmentInfo attachmentInfo) { - return UnitOfWorkExecutor.executeInUnitOfWork( - application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem( - taskId, - wi -> HumanTaskHelper.addAttachment(wi, attachmentInfo, policy.value().getName()), - policy))); + return updateUserTaskInstance(process, id, taskId, policy, userTaskInstance -> { + Attachment attachment = new Attachment(UUID.randomUUID().toString(), policy.getUser()); + attachment.setName(attachmentInfo.getName()); + attachment.setContent(attachmentInfo.getUri()); + attachment.setUpdatedAt(new Date()); + userTaskInstance.addAttachment(attachment); + return attachment; + }); } @Override @@ -312,15 +357,15 @@ public Optional updateAttachment(Process proces String taskId, String attachmentId, SecurityPolicy policy, - AttachmentInfo attachment) { - return UnitOfWorkExecutor.executeInUnitOfWork( - application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem( - taskId, - wi -> HumanTaskHelper.updateAttachment(wi, attachmentId, attachment, policy.value().getName()), - policy))); + AttachmentInfo attachmentInfo) { + return updateUserTaskInstance(process, id, taskId, policy, userTaskInstance -> { + Attachment attachment = new Attachment(attachmentId, policy.getUser()); + attachment.setName(attachmentInfo.getName()); + attachment.setContent(attachmentInfo.getUri()); + attachment.setUpdatedAt(new Date()); + userTaskInstance.updateAttachment(attachment); + return attachment; + }); } @Override @@ -329,14 +374,38 @@ public Optional deleteAttachment(Process process, String taskId, String attachmentId, SecurityPolicy policy) { + return updateUserTaskInstance(process, id, taskId, policy, userTaskInstance -> { + Attachment attachment = new Attachment(attachmentId, policy.getUser()); + userTaskInstance.removeAttachment(attachment); + return Boolean.TRUE; + }); + } + + private Optional updateUserTaskInstance(Process process, + String id, + String taskId, + SecurityPolicy policy, + Function consumer) { return UnitOfWorkExecutor.executeInUnitOfWork( - application.unitOfWorkManager(), () -> process - .instances() - .findById(id) - .map(pi -> pi.updateWorkItem( - taskId, - wi -> HumanTaskHelper.deleteAttachment(wi, attachmentId, policy.value().getName()), - policy))); + application.unitOfWorkManager(), () -> { + ProcessInstance processInstance = process.instances().findById(id).orElseThrow(() -> new ProcessInstanceNotFoundException(id)); + WorkItem wi = processInstance.workItem(taskId); + String referenceId = wi.getExternalReferenceId(); + if (referenceId == null) { + return Optional.empty(); + } + String[] data = referenceId.split(":"); + UserTasks userTasks = application.get(UserTasks.class); + UserTask userTask = userTasks.userTaskById(data[0]); + Optional instance = userTask.instances().findById(data[0]); + if (instance.isEmpty()) { + return Optional.empty(); + } + UserTaskInstance userTaskInstance = instance.get(); + R outcome = consumer.apply(userTaskInstance); + userTask.instances().update(userTaskInstance); + return Optional.ofNullable(outcome); + }); } @Override @@ -345,10 +414,7 @@ public Optional getAttachment(Process process, String taskId, String attachmentId, SecurityPolicy policy) { - return process.instances().findById(id) - .map(pi -> HumanTaskHelper.findTask(pi, taskId, policy)) - .map(HumanTaskWorkItem::getAttachments) - .map(attachments -> attachments.get(attachmentId)); + return retrieveUserTaskInstance(process, id, taskId, policy, ut -> ut.findAttachmentById(attachmentId)); } @Override @@ -356,10 +422,7 @@ public Optional> getAttachments(Process String id, String taskId, SecurityPolicy policy) { - return process.instances().findById(id) - .map(pi -> HumanTaskHelper.findTask(pi, taskId, policy)) - .map(HumanTaskWorkItem::getAttachments) - .map(Map::values); + return retrieveUserTaskInstance(process, id, taskId, policy, ut -> ut.getAttachments()); } @Override @@ -368,10 +431,7 @@ public Optional getComment(Process process, String taskId, String commentId, SecurityPolicy policy) { - return process.instances().findById(id) - .map(pi -> HumanTaskHelper.findTask(pi, taskId, policy)) - .map(HumanTaskWorkItem::getComments) - .map(comments -> comments.get(commentId)); + return retrieveUserTaskInstance(process, id, taskId, policy, ut -> ut.findCommentById(commentId)); } @Override @@ -379,36 +439,32 @@ public Optional> getComments(Process pr String id, String taskId, SecurityPolicy policy) { - return process.instances().findById(id) - .map(pi -> HumanTaskHelper.findTask(pi, taskId, policy)) - .map(HumanTaskWorkItem::getComments) - .map(Map::values); + return retrieveUserTaskInstance(process, id, taskId, policy, ut -> ut.getComments()); } - @Override - public , R> Optional signalProcessInstance(Process process, String id, Object data, String signalName) { - return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), - () -> process.instances().findById(id) - .map(pi -> { - pi.send(Sig.of(signalName, data)); - return pi.checkError().variables().toModel(); - })); - } - - //Schema - @Override - public Map getSchemaAndPhases(Process process, + private Optional retrieveUserTaskInstance(Process process, String id, String taskId, - String taskName, - SecurityPolicy policy) { - return JsonSchemaUtil.addPhases( - process, - application.config().get(ProcessConfig.class).workItemHandlers().forName("Human Task"), - id, - taskId, - new Policy[] { policy }, - JsonSchemaUtil.load(Thread.currentThread().getContextClassLoader(), process.id(), taskName)); + SecurityPolicy policy, + Function consumer) { + return UnitOfWorkExecutor.executeInUnitOfWork( + application.unitOfWorkManager(), () -> { + ProcessInstance processInstance = process.instances().findById(id).orElseThrow(() -> new ProcessInstanceNotFoundException(id)); + WorkItem wi = processInstance.workItem(taskId); + String referenceId = wi.getExternalReferenceId(); + if (referenceId == null) { + return Optional.empty(); + } + String[] data = referenceId.split(":"); + UserTasks userTasks = application.get(UserTasks.class); + UserTask userTask = userTasks.userTaskById(data[0]); + Optional instance = userTask.instances().findById(data[0]); + if (instance.isEmpty()) { + return Optional.empty(); + } + UserTaskInstance userTaskInstance = instance.get(); + R outcome = consumer.apply(userTaskInstance); + return Optional.ofNullable(outcome); + }); } - } diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java index c62569a348c..67f835b37ad 100755 --- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java +++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/TimerTest.java @@ -18,13 +18,17 @@ */ package org.jbpm.process; +import java.util.concurrent.TimeUnit; + import org.drools.core.common.InternalWorkingMemory; import org.drools.kiesession.session.ProcessRuntimeFactory; import org.jbpm.process.instance.InternalProcessRuntime; import org.jbpm.process.instance.ProcessRuntimeFactoryServiceImpl; import org.jbpm.ruleflow.instance.RuleFlowProcessInstance; import org.jbpm.test.util.AbstractBaseTest; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; import org.kie.kogito.jobs.DurationExpirationTime; import org.kie.kogito.jobs.ExactExpirationTime; @@ -52,6 +56,8 @@ public void addLogger() { } @Test + @Timeout(value = 10L, unit = TimeUnit.SECONDS) + @Disabled public void testTimer() { KogitoProcessRuntime kruntime = createKogitoProcessRuntime(); diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java index 20186b16a06..40e2b91a762 100755 --- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java +++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java @@ -33,9 +33,9 @@ import org.jbpm.process.core.datatype.impl.type.StringDataType; import org.jbpm.process.core.impl.ParameterDefinitionImpl; import org.jbpm.process.core.impl.WorkImpl; -import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; -import org.jbpm.process.instance.impl.demo.MockDataWorkItemHandler; import org.jbpm.process.test.Person; +import org.jbpm.process.workitem.builtin.DoNothingWorkItemHandler; +import org.jbpm.process.workitem.builtin.MockDataWorkItemHandler; import org.jbpm.ruleflow.core.RuleFlowProcess; import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory; import org.jbpm.test.util.AbstractBaseTest; @@ -49,7 +49,7 @@ import org.kie.api.definition.process.WorkflowElementIdentifier; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.process.workitems.KogitoWorkItemHandlerNotFoundException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerNotFoundException; import org.slf4j.LoggerFactory; import static org.assertj.core.api.Assertions.assertThat; diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/core/context/exception/ExceptionHandlerPolicyTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/core/context/exception/ExceptionHandlerPolicyTest.java index cd050360035..3f68ecb2fcc 100644 --- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/core/context/exception/ExceptionHandlerPolicyTest.java +++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/core/context/exception/ExceptionHandlerPolicyTest.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; import static org.assertj.core.api.Assertions.assertThat; diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/TestWorkItemHandler.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/TestWorkItemHandler.java index d44bc83c63a..b6407c4c825 100755 --- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/TestWorkItemHandler.java +++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/TestWorkItemHandler.java @@ -20,26 +20,31 @@ import java.util.Deque; import java.util.LinkedList; +import java.util.Optional; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; /** * */ -public class TestWorkItemHandler implements KogitoWorkItemHandler { +public class TestWorkItemHandler extends DefaultKogitoWorkItemHandler { public Deque workItems = new LinkedList<>(); @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { this.workItems.add(workItem); + return Optional.empty(); } @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { this.workItems.add(workItem); + return Optional.empty(); } public Deque getWorkItems() { diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/util/JsonSchemaUtilTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/util/JsonSchemaUtilTest.java index 97d9b15bf48..00816c2dd6c 100644 --- a/jbpm/jbpm-flow/src/test/java/org/jbpm/util/JsonSchemaUtilTest.java +++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/util/JsonSchemaUtilTest.java @@ -25,10 +25,10 @@ import java.util.Map; import java.util.Optional; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler; import org.junit.jupiter.api.Test; import org.kie.kogito.Config; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.Policy; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; @@ -36,7 +36,7 @@ import org.kie.kogito.process.ProcessInstances; import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.WorkItemHandlerConfig; -import org.kie.kogito.process.workitem.Policy; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -105,7 +105,7 @@ void testJsonSchema() throws IOException { @Test void testJsonSchemaPhases() throws IOException { InputStream in = new ByteArrayInputStream(example.getBytes()); - Policy[] policies = new Policy[0]; + Policy[] policies = new Policy[0]; Map schemaMap = JsonSchemaUtil.load(in); in.close(); Process process = mock(Process.class); @@ -121,7 +121,7 @@ void testJsonSchemaPhases() throws IOException { when(config.get(any())).thenReturn(processConfig); WorkItemHandlerConfig workItemHandlerConfig = mock(WorkItemHandlerConfig.class); when(processConfig.workItemHandlers()).thenReturn(workItemHandlerConfig); - KogitoWorkItemHandler workItemHandler = new HumanTaskWorkItemHandler(); + KogitoWorkItemHandler workItemHandler = new DefaultKogitoWorkItemHandler(); when(workItemHandlerConfig.forName("Human Task")).thenReturn(workItemHandler); schemaMap = JsonSchemaUtil.addPhases(process, workItemHandler, "pepe", "task", policies, schemaMap); assertThat(((Collection) schemaMap.get("phases"))).isNotEmpty(); diff --git a/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessConfigTest.java b/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessConfigTest.java index 6bccb374c83..2f0b75255dd 100644 --- a/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessConfigTest.java +++ b/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessConfigTest.java @@ -22,7 +22,7 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.WorkItemHandlerConfig; diff --git a/jbpm/jbpm-tests/pom.xml b/jbpm/jbpm-tests/pom.xml index c89301e3fb3..230f0cd2c4f 100644 --- a/jbpm/jbpm-tests/pom.xml +++ b/jbpm/jbpm-tests/pom.xml @@ -49,7 +49,10 @@ org.kie.kogito jbpm-flow - + + org.kie.kogito + process-workitems + org.glassfish.jaxb @@ -136,6 +139,7 @@ org.codehaus.mojo build-helper-maven-plugin + ${version.maven-help-plugin} add-test-source diff --git a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/ExceptionOnPurposeHandler.java b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/ExceptionOnPurposeHandler.java index f9c2e767bab..984d001e7bc 100755 --- a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/ExceptionOnPurposeHandler.java +++ b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/ExceptionOnPurposeHandler.java @@ -18,18 +18,19 @@ */ package org.jbpm.bpmn2.objects; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import java.util.Optional; -public class ExceptionOnPurposeHandler implements KogitoWorkItemHandler { +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; + +public class ExceptionOnPurposeHandler extends DefaultKogitoWorkItemHandler { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { throw new RuntimeException("Unknown error, status code 400"); } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - } } diff --git a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestUserTaskWorkItemHandler.java b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestUserTaskWorkItemHandler.java new file mode 100644 index 00000000000..258a92af0eb --- /dev/null +++ b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestUserTaskWorkItemHandler.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.bpmn2.objects; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCycle; +import org.kie.kogito.internal.process.workitem.WorkItemPhaseState; +import org.kie.kogito.internal.process.workitem.WorkItemTerminationType; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; +import org.kie.kogito.process.workitems.impl.DefaultWorkItemLifeCycle; +import org.kie.kogito.process.workitems.impl.DefaultWorkItemLifeCyclePhase; + +public class TestUserTaskWorkItemHandler extends DefaultKogitoWorkItemHandler { + public static final WorkItemPhaseState INACTIVE = WorkItemPhaseState.initialized(); + public static final WorkItemPhaseState COMPLETE = WorkItemPhaseState.of("Completed", WorkItemTerminationType.COMPLETE); + public static final WorkItemPhaseState ABORT = WorkItemPhaseState.of("Aborted", WorkItemTerminationType.ABORT); + public static final WorkItemPhaseState ACTIVE = WorkItemPhaseState.of("Activated"); + public static final WorkItemPhaseState RESERVE = WorkItemPhaseState.of("Reserved"); + + private List workItems = new ArrayList<>(); + + @Override + public WorkItemLifeCycle initialize() { + DefaultWorkItemLifeCyclePhase complete = new DefaultWorkItemLifeCyclePhase("complete", RESERVE, COMPLETE, this::completeWorkItemHandler); + DefaultWorkItemLifeCyclePhase abort = new DefaultWorkItemLifeCyclePhase("abort", RESERVE, ABORT, this::abortWorkItemHandler); + DefaultWorkItemLifeCyclePhase claim = new DefaultWorkItemLifeCyclePhase("claim", ACTIVE, RESERVE, this::claimWorkItemHandler); + DefaultWorkItemLifeCyclePhase active = new DefaultWorkItemLifeCyclePhase("activate", INACTIVE, ACTIVE, this::activateWorkItemHandler); + + return new DefaultWorkItemLifeCycle(active, claim, abort, complete); + } + + public Optional claimWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + return Optional.empty(); + } + + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + workItems.add(workItem); + + String potentialOwners = (String) workItem.getParameter("ActorId"); + potentialOwners = potentialOwners == null ? (String) workItem.getParameter("SwimlaneActorId") : potentialOwners; + + if (potentialOwners != null) { + String[] owners = potentialOwners.split(","); + workItem.setOutput("ACTUAL_OWNER", owners[0]); + return Optional.of(workItemLifeCycle.newTransition("claim", workItem.getPhaseStatus(), workItem.getResults())); + } + + return Optional.empty(); + } + + @Override + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + workItems.remove(workItem); + return Optional.empty(); + } + + @Override + public Optional completeWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + workItems.remove(workItem); + return Optional.empty(); + } + + public KogitoWorkItem getWorkItem() { + switch (workItems.size()) { + case 0: + return null; + case 1: + KogitoWorkItem result = workItems.get(0); + this.workItems.clear(); + return result; + default: + throw new IllegalArgumentException("More than one work item active"); + } + } + + public List getWorkItems() { + List result = new ArrayList<>(workItems); + workItems.clear(); + return result; + } + +} diff --git a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestWorkItemHandler.java b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestWorkItemHandler.java index 9d6a939a11b..ba284812044 100755 --- a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestWorkItemHandler.java +++ b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/objects/TestWorkItemHandler.java @@ -20,47 +20,34 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Optional; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.workitem.Active; -import org.jbpm.process.instance.impl.workitem.Complete; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; -import org.kie.kogito.process.workitem.Transition; -import org.kie.kogito.process.workitems.InternalKogitoWorkItem; -import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public class TestWorkItemHandler implements KogitoWorkItemHandler { +public class TestWorkItemHandler extends DefaultKogitoWorkItemHandler { private List workItems = new ArrayList<>(); - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { workItems.add(workItem); - - if (workItem instanceof HumanTaskWorkItem) { - InternalHumanTaskWorkItem humanTaskWorkItem = (InternalHumanTaskWorkItem) workItem; - - humanTaskWorkItem.setPhaseId(Active.ID); - humanTaskWorkItem.setPhaseStatus(Active.STATUS); - } - } - - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + return Optional.empty(); } public KogitoWorkItem getWorkItem() { - if (workItems.size() == 0) { - return null; - } - if (workItems.size() == 1) { - KogitoWorkItem result = workItems.get(0); - this.workItems.clear(); - return result; - } else { - throw new IllegalArgumentException("More than one work item active"); + switch (workItems.size()) { + case 0: + return null; + case 1: + KogitoWorkItem result = workItems.get(0); + this.workItems.clear(); + return result; + default: + throw new IllegalArgumentException("More than one work item active"); } } @@ -70,12 +57,4 @@ public List getWorkItems() { return result; } - @Override - public void transitionToPhase(KogitoWorkItem workItem, KogitoWorkItemManager manager, Transition transition) { - - if (transition.phase().equals(Complete.ID)) { - ((InternalKogitoWorkItem) workItem).setResults((Map) transition.data()); - ((InternalKogitoWorkItemManager) manager).internalCompleteWorkItem((InternalKogitoWorkItem) workItem); - } - } } diff --git a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/services/AlwaysThrowingComponent.java b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/services/AlwaysThrowingComponent.java index 49d42aecbce..c4d51288213 100644 --- a/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/services/AlwaysThrowingComponent.java +++ b/jbpm/jbpm-tests/src/main/java/org/jbpm/bpmn2/services/AlwaysThrowingComponent.java @@ -18,7 +18,7 @@ */ package org.jbpm.bpmn2.services; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; public class AlwaysThrowingComponent { diff --git a/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsLazyCreating.bpmn2 b/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsLazyCreating.bpmn2 index 20636526680..de3f169173e 100755 --- a/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsLazyCreating.bpmn2 +++ b/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsLazyCreating.bpmn2 @@ -42,7 +42,7 @@ - + coId @@ -52,9 +52,9 @@ instanceMetadata coId - - . - mydoc/mynode + + mydoc/mynode + . diff --git a/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsXmlLiteral.bpmn2 b/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsXmlLiteral.bpmn2 index 2ab9e2102d7..f063114ee6d 100755 --- a/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsXmlLiteral.bpmn2 +++ b/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataInputAssociationsXmlLiteral.bpmn2 @@ -42,7 +42,7 @@ - + coId diff --git a/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataOutputAssociationsXmlNode.bpmn2 b/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataOutputAssociationsXmlNode.bpmn2 index 7216762163c..0059388407f 100755 --- a/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataOutputAssociationsXmlNode.bpmn2 +++ b/jbpm/jbpm-tests/src/test/bpmn/org/jbpm/bpmn2/data/BPMN2-DataOutputAssociationsXmlNode.bpmn2 @@ -52,7 +52,7 @@ output instanceMetadata - + . . @@ -72,7 +72,7 @@ instanceMetadata coId - + @hello . diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java index b4b31f7111f..c6887717cee 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java @@ -77,12 +77,11 @@ import org.jbpm.bpmn2.flow.UserTaskProcess; import org.jbpm.bpmn2.flow.XORSameTargetModel; import org.jbpm.bpmn2.flow.XORSameTargetProcess; -import org.jbpm.bpmn2.handler.ReceiveTaskHandler; -import org.jbpm.bpmn2.handler.SendTaskHandler; import org.jbpm.bpmn2.objects.Account; import org.jbpm.bpmn2.objects.Address; import org.jbpm.bpmn2.objects.HelloService; import org.jbpm.bpmn2.objects.Person; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.bpmn2.service.ServiceProcessModel; import org.jbpm.bpmn2.service.ServiceProcessProcess; @@ -151,8 +150,10 @@ import org.jbpm.process.core.context.variable.VariableScope; import org.jbpm.process.instance.event.listeners.RuleAwareProcessEventListener; import org.jbpm.process.instance.event.listeners.TriggerRulesEventListener; -import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.DoNothingWorkItemHandler; +import org.jbpm.process.workitem.builtin.ReceiveTaskHandler; +import org.jbpm.process.workitem.builtin.SendTaskHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.util.ProcessCompletedCountDownProcessEventListener; import org.jbpm.test.utils.EventTrackerProcessListener; import org.jbpm.test.utils.ProcessTestHelper; @@ -196,8 +197,9 @@ import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; @@ -488,7 +490,7 @@ public void testUserTaskWithDataStoreScenario() throws Exception { @Test public void testUserTask() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskProcess.newProcess(app); UserTaskModel model = processDefinition.createModel(); @@ -505,7 +507,7 @@ public void testUserTask() { @Test public void testUserTaskActorAssignment() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskActorProcess.newProcess(app); UserTaskActorModel model = processDefinition.createModel(); @@ -552,7 +554,7 @@ public void testUserTaskActorAssignmentNoPolicyFailure() { KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap()); + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "bayron"); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); } @@ -606,7 +608,7 @@ public void testUserTaskGroupAssignmentNoPolicyFailure() { KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap()); + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "bayron"); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); } @@ -614,7 +616,7 @@ public void testUserTaskGroupAssignmentNoPolicyFailure() { @Test public void testUserTaskNoneAssignmentFailure() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskNoneProcess.newProcess(app); UserTaskNoneModel model = processDefinition.createModel(); @@ -623,16 +625,18 @@ public void testUserTaskNoneAssignmentFailure() { assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); - - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "john", "HR"); - + try { + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "john", "HR"); + } catch (Throwable e) { + assertThat(e).isInstanceOf(InvalidTransitionException.class); + } assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test public void testUserTaskNoneAssignmentNoPolicyFailure() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskNoneProcess.newProcess(app); UserTaskNoneModel model = processDefinition.createModel(); @@ -641,16 +645,18 @@ public void testUserTaskNoneAssignmentNoPolicyFailure() { assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); - - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap()); - + try { + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), null); + } catch (Throwable e) { + assertThat(e).isInstanceOf(InvalidTransitionException.class); + } assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test public void testUserTaskActorAndGroupAssignmentWithActor() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskActorGroupProcess.newProcess(app); UserTaskActorGroupModel model = processDefinition.createModel(); @@ -686,7 +692,7 @@ public void testUserTaskActorAndGroupAssignmentWithGroup() { @Test public void testUserTaskActorAndGroupAssignmentFailure() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskActorGroupProcess.newProcess(app); UserTaskActorGroupModel model = processDefinition.createModel(); @@ -714,7 +720,7 @@ public void testUserTaskActorAndGroupAssignmentNoPolicyFailure() { KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap()); + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "bayron"); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); } @@ -730,7 +736,7 @@ public void testUserTaskVerifyParameters() { processInstance.start(); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("ActorId")).isEqualTo("john"); final String pId = processInstance.id(); @@ -782,6 +788,7 @@ public void testSubProcessWithEntryExitScripts() throws Exception { Application app = ProcessTestHelper.newApplication(); EventTrackerProcessListener listener = new EventTrackerProcessListener(); ProcessTestHelper.registerProcessEventListener(app, listener); + ProcessTestHelper.registerHandler(app, "Human Task", new TestUserTaskWorkItemHandler()); org.kie.kogito.process.Process process = SubProcessWithEntryExitScriptsProcess.newProcess(app); ProcessInstance processInstance = process.createInstance(process.createModel()); @@ -868,7 +875,7 @@ public void testCallActivity2() { assertThat(processInstance.status()).isEqualTo(org.jbpm.process.instance.ProcessInstance.STATE_ACTIVE); assertThat(processInstance.variables().getY()).isEqualTo("new value"); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("ActorId")).isEqualTo("krisv"); processInstance.completeWorkItem(workItem.getStringId(), null); @@ -1029,9 +1036,8 @@ public void testAdHocProcessDynamicTask() throws Exception { TestWorkItemHandler workItemHandler2 = new TestWorkItemHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("OtherTask", workItemHandler2); - DynamicUtils.addDynamicWorkItem(processInstance, kruntime.getKieSession(), "OtherTask", - new HashMap<>()); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler2.getWorkItem(); + DynamicUtils.addDynamicWorkItem(processInstance, kruntime.getKieSession(), "OtherTask", new HashMap<>()); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler2.getWorkItem(); assertThat(workItem).isNotNull(); kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), null); kruntime.signalEvent("User1", null, processInstance.getStringId()); @@ -1110,17 +1116,19 @@ public void testSendTask() { @Test public void testReceiveTask() throws Exception { Application app = ProcessTestHelper.newApplication(); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/task/BPMN2-ReceiveTask.bpmn2"); - ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(kruntime); + ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(); ProcessTestHelper.registerHandler(app, "Receive Task", receiveTaskHandler); org.kie.kogito.process.Process processDefinition = ReceiveTaskProcess.newProcess(app); ReceiveTaskModel model = processDefinition.createModel(); org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - receiveTaskHandler.setKnowledgeRuntime(kruntime); - receiveTaskHandler.messageReceived("HelloMessage", "Hello john!"); - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "john"); + + Map results = new HashMap<>(); + results.put("Message", "Hello john!"); + + ProcessTestHelper.completeWorkItem(instance, results); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } @@ -1258,7 +1266,7 @@ public void testCallActivityWithSubProcessWaitState() { processInstance.start(); assertThat(processInstance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); subProcessInstance.completeWorkItem(workItem.getStringId(), Collections.emptyMap()); assertThat(processInstance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED); @@ -1281,7 +1289,7 @@ public void testUserTaskWithBooleanOutput() { processInstance.start(); assertThat(processInstance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("ActorId")).isEqualTo("john"); HashMap output = new HashMap<>(); @@ -1293,7 +1301,7 @@ public void testUserTaskWithBooleanOutput() { @Test public void testUserTaskWithSimData() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskWithSimulationMetaDataProcess.newProcess(app); UserTaskWithSimulationMetaDataModel model = processDefinition.createModel(); @@ -1343,7 +1351,7 @@ public void testCallActivityWithBoundaryErrorEventWithWaitState() { ProcessInstance processInstance = process.createInstance(model); processInstance.start(); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); subProcessInstance.completeWorkItem(workItem.getStringId(), Collections.emptyMap()); @@ -1573,7 +1581,7 @@ public void testUserTaskParametrizedInput() { processInstance.start(); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("Description").toString().trim()).isEqualTo("Executing task of process instance " + processInstance.id() + " as work item with Hello"); processInstance.completeWorkItem(workItem.getStringId(), null); @@ -1623,7 +1631,7 @@ public void testSubProcessInAdHocProcess() { instance.start(); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); instance.completeWorkItem(workItem.getStringId(), Collections.emptyMap()); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); @@ -1862,7 +1870,7 @@ public void testUserTaskWithExpressionsForIO() { instance.start(); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("ActorId")).isEqualTo("john"); assertThat(workItem.getParameter("personName")).isEqualTo("john"); @@ -1887,7 +1895,7 @@ public void testCallActivitykWithExpressionsForIO() { assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); Person person = instance.variables().getPerson(); assertThat(person.getName()).isEqualTo("new value"); - org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem = workItemHandler.getWorkItem(); + org.kie.kogito.internal.process.workitem.KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("ActorId")).isEqualTo("krisv"); instance.completeWorkItem(workItem.getStringId(), Collections.emptyMap()); @@ -1908,7 +1916,7 @@ public void testCallSubprocessWithGroup() { instance.start(); assertThat(instance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_ACTIVE); - List workItems = workItemHandler.getWorkItems(); + List workItems = workItemHandler.getWorkItems(); workItems.forEach(workItem -> { assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("GroupId")).isEqualTo("GRUPA TESTOWA"); diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CollaborationTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CollaborationTest.java index fb88b9b55b5..3f214b8f568 100644 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CollaborationTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CollaborationTest.java @@ -27,7 +27,7 @@ import org.jbpm.bpmn2.collaboration.CollaborationIntermediateMessageProcess; import org.jbpm.bpmn2.collaboration.CollaborationStartMessageModel; import org.jbpm.bpmn2.collaboration.CollaborationStartMessageProcess; -import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; +import org.jbpm.process.workitem.builtin.DoNothingWorkItemHandler; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Test; import org.kie.api.event.process.ProcessStartedEvent; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CompensationTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CompensationTest.java index ad6d9095708..ca217ba269f 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CompensationTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/CompensationTest.java @@ -39,7 +39,7 @@ import org.jbpm.bpmn2.compensation.UserTaskCompensationProcess; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.process.core.context.exception.CompensationScope; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -50,7 +50,7 @@ import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.impl.Sig; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/DataTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/DataTest.java index 3183b0b06cb..95f5c0bdcf5 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/DataTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/DataTest.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -61,19 +62,22 @@ import org.jbpm.bpmn2.data.ImportProcess; import org.jbpm.bpmn2.flow.DataOutputAssociationsHumanTaskModel; import org.jbpm.bpmn2.flow.DataOutputAssociationsHumanTaskProcess; +import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.bpmn2.xml.ProcessHandler; import org.jbpm.process.core.datatype.impl.type.ObjectDataType; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.kie.kogito.Application; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -202,15 +206,14 @@ public void testXpathExpression() throws Exception { @Test public void testDataInputAssociations() throws Exception { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { assertThat(workItem.getParameter("coId")).isEqualTo("hello world"); + return Optional.empty(); } + }); Document document = DocumentBuilderFactory @@ -224,20 +227,19 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test public void testDataInputAssociationsWithStringObject() { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } - - @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { assertThat(workItem.getParameter("coId")).isEqualTo("hello"); + return Optional.empty(); } + }); org.kie.kogito.process.Process processDefinition = DataInputAssociationsStringObjectProcess.newProcess(app); @@ -246,6 +248,7 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); } /** @@ -254,48 +257,43 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) @Test public void testDataInputAssociationsWithLazyLoading() throws Exception { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Element coIdParamObj = (Element) workItem.getParameter("coId"); - assertThat(coIdParamObj.getNodeName()).isEqualTo("mydoc"); - assertThat(coIdParamObj.getFirstChild().getNodeName()).isEqualTo("mynode"); - assertThat(coIdParamObj.getFirstChild().getFirstChild().getNodeName()).isEqualTo("user"); - assertThat(coIdParamObj.getFirstChild().getFirstChild().getAttributes().getNamedItem("hello").getNodeValue()).isEqualTo("hello world"); + assertThat(coIdParamObj.getNodeName()).isEqualTo("mynode"); + assertThat(coIdParamObj.getFirstChild().getNodeName()).isEqualTo("user"); + assertThat(coIdParamObj.getFirstChild().getAttributes().getNamedItem("hello").getNodeValue()).isEqualTo("hello world"); + return Optional.empty(); } + }); Document document = DocumentBuilderFactory .newInstance() .newDocumentBuilder() - .parse(new ByteArrayInputStream("".getBytes())); - Map params = new HashMap<>(); - params.put("instanceMetadata", document.getFirstChild()); + .parse(new ByteArrayInputStream("".getBytes())); org.kie.kogito.process.Process processDefinition = DataInputAssociationsLazyCreatingProcess.newProcess(app); DataInputAssociationsLazyCreatingModel model = processDefinition.createModel(); - model.setInstanceMetadata(document.getFirstChild()); + model.setInstanceMetadata(document); org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test public void testDataInputAssociationsWithString() { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } - + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { assertThat(workItem.getParameter("coId")).isEqualTo("hello"); + return Optional.empty(); } + }); org.kie.kogito.process.Process processDefinition = DataInputAssociationsStringProcess.newProcess(app); @@ -303,20 +301,20 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test public void testDataInputAssociationsWithStringWithoutQuotes() { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { assertThat(workItem.getParameter("coId")).isEqualTo("hello"); + return Optional.empty(); } + }); org.kie.kogito.process.Process processDefinition = DataInputAssociationsStringNoQuotesProcess.newProcess(app); @@ -324,21 +322,20 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test public void testDataInputAssociationsWithXMLLiteral() { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } - + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { assertThat(((org.w3c.dom.Node) workItem.getParameter("coId")).getNodeName()).isEqualTo("id"); assertThat(((org.w3c.dom.Node) workItem.getParameter("coId")).getFirstChild().getTextContent()).isEqualTo("some text"); + return Optional.empty(); } + }); org.kie.kogito.process.Process processDefinition = DataInputAssociationsXmlLiteralProcess.newProcess(app); @@ -346,6 +343,7 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); } /** @@ -355,26 +353,15 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) @Disabled public void testDataInputAssociationsWithTwoAssigns() throws Exception { kruntime = createKogitoProcessRuntime("BPMN2-DataInputAssociations-two-assigns.bpmn2"); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", - new KogitoWorkItemHandler() { - - public void abortWorkItem(KogitoWorkItem manager, - KogitoWorkItemManager mgr) { - - } - - public void executeWorkItem(KogitoWorkItem workItem, - KogitoWorkItemManager mgr) { - assertThat(((Element) workItem.getParameter("Comment")).getNodeName()).isEqualTo("foo"); - // assertEquals("mynode", ((Element) - // workItem.getParameter("Comment")).getFirstChild().getNodeName()); - // assertEquals("user", ((Element) - // workItem.getParameter("Comment")).getFirstChild().getFirstChild().getNodeName()); - // assertEquals("hello world", ((Element) - // workItem.getParameter("coId")).getFirstChild().getFirstChild().getAttributes().getNamedItem("hello").getNodeValue()); - } - - }); + kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new DefaultKogitoWorkItemHandler() { + + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + assertThat(((Element) workItem.getParameter("Comment")).getNodeName()).isEqualTo("foo"); + return Optional.empty(); + } + + }); Document document = DocumentBuilderFactory .newInstance() .newDocumentBuilder() @@ -382,9 +369,8 @@ public void executeWorkItem(KogitoWorkItem workItem, .getBytes())); Map params = new HashMap<>(); params.put("instanceMetadata", document.getFirstChild()); - KogitoProcessInstance processInstance = kruntime.startProcess("process", - params); - + KogitoProcessInstance processInstance = kruntime.startProcess("process", params); + assertThat(processInstance.getState()).isEqualTo(ProcessInstance.STATE_ACTIVE); } @Test @@ -392,13 +378,10 @@ public void testDataOutputAssociationsforHumanTask() { Application app = ProcessTestHelper.newApplication(); List documents = new ArrayList<>(); List workItems = new ArrayList<>(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; try { @@ -414,9 +397,12 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) processMetadata.setAttribute("primaryname", "my_result"); documents.add(processMetadaDoc); results.put("output", processMetadata); + workItems.add(workItem); - mgr.completeWorkItem(workItem.getStringId(), results); + + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), results)); } + }); org.kie.kogito.process.Process processDefinition = DataOutputAssociationsHumanTaskProcess.newProcess(app); @@ -424,6 +410,7 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); assertThat(documents.size()).isEqualTo(1); NodeList nodeList = documents.get(0).getElementsByTagName("previoustasksowner"); @@ -434,18 +421,17 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) KogitoWorkItem workItem = workItems.get(0); assertThat(workItem.getResults().get("output")).isInstanceOf(org.w3c.dom.Node.class); assertThat((org.w3c.dom.Node) (workItem.getResults().get("output"))).isEqualTo(nodeList.item(0)); + + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); + } @Test public void testDataOutputAssociations() { Application app = ProcessTestHelper.newApplication(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } - - @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { try { Document document = DocumentBuilderFactory .newInstance() @@ -453,11 +439,12 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) .parse(new ByteArrayInputStream("".getBytes())); Map params = new HashMap<>(); params.put("output", document.getFirstChild()); - mgr.completeWorkItem(workItem.getStringId(), params); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), params)); } catch (Throwable e) { throw new RuntimeException(e); } } + }); org.kie.kogito.process.Process processDefinition = DataOutputAssociationsProcess.newProcess(app); @@ -465,20 +452,19 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.variables()).isNotNull(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @Test public void testDataOutputAssociationsXmlNode() { Application app = ProcessTestHelper.newApplication(); - List workItems = new ArrayList<>(); List documents = new ArrayList<>(); - ProcessTestHelper.registerHandler(app, "Human Task", new KogitoWorkItemHandler() { - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { - } + List workItems = new ArrayList<>(); + ProcessTestHelper.registerHandler(app, "Human Task", new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { try { Document document = DocumentBuilderFactory .newInstance() @@ -486,13 +472,15 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) .parse(new ByteArrayInputStream("".getBytes())); Map params = new HashMap<>(); params.put("output", document.getFirstChild()); - workItems.add(workItem); documents.add(document); - mgr.completeWorkItem(workItem.getStringId(), params); + workItems.add(workItem); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), params)); + } catch (Throwable e) { throw new RuntimeException(e); } } + }); org.kie.kogito.process.Process processDefinition = DataOutputAssociationsXmlNodeProcess.newProcess(app); @@ -500,6 +488,7 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); + assertThat(instance.status()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); assertThat(workItems.size()).isGreaterThanOrEqualTo(1); KogitoWorkItem workItem = workItems.get(0); @@ -508,6 +497,10 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager mgr) org.w3c.dom.Node node = documents.get(0).getFirstChild(); assertThat(workItem.getResults().get("output")).isInstanceOf(org.w3c.dom.Node.class); assertThat((org.w3c.dom.Node) (workItem.getResults().get("output"))).isEqualTo(node); + + assertThat(instance.variables().getInstanceMetadata()).isNotNull(); + assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); + } @Test @@ -515,12 +508,14 @@ public void testDefaultProcessVariableValue() throws Exception { kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/data/BPMN2-CorrelationKey.bpmn2"); + kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new TestWorkItemHandler()); Map parameters = new HashMap(); KogitoWorkflowProcessInstance processInstance = (KogitoWorkflowProcessInstance) kruntime.startProcess("CorrelationKey", parameters); assertThat(processInstance.getVariable("procVar")).isEqualTo("defaultProc"); assertThat(processInstance.getVariable("intVar")).isEqualTo(1); + assertThat(processInstance.getState()).isEqualTo(ProcessInstance.STATE_ACTIVE); } diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EndEventTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EndEventTest.java index bfed716fa30..b461a0c7439 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EndEventTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EndEventTest.java @@ -45,7 +45,7 @@ import org.jbpm.bpmn2.event.SignalEndEventProcess; import org.jbpm.bpmn2.event.SubprocessWithParallelSplitTerminateModel; import org.jbpm.bpmn2.event.SubprocessWithParallelSplitTerminateProcess; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Test; import org.kie.kogito.Application; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ErrorEventTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ErrorEventTest.java index 213fbb95043..6840a87d13d 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ErrorEventTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ErrorEventTest.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.jbpm.bpmn2.error.BoundaryErrorEventDefaultHandlerByErrorCodeModel; import org.jbpm.bpmn2.error.BoundaryErrorEventDefaultHandlerByErrorCodeProcess; @@ -52,23 +53,26 @@ import org.jbpm.bpmn2.event.BoundaryErrorEventDefaultHandlerWithoutErrorCodeWithoutStructureRefProcess; import org.jbpm.bpmn2.event.BoundaryErrorEventSubProcessExceptionMappingModel; import org.jbpm.bpmn2.event.BoundaryErrorEventSubProcessExceptionMappingProcess; -import org.jbpm.bpmn2.handler.SignallingTaskHandlerDecorator; import org.jbpm.bpmn2.objects.ExceptionOnPurposeHandler; import org.jbpm.bpmn2.objects.ExceptionService; import org.jbpm.bpmn2.objects.MyError; import org.jbpm.bpmn2.objects.Person; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.bpmn2.service.ExceptionServiceProcessErrorSignallingModel; import org.jbpm.bpmn2.service.ExceptionServiceProcessErrorSignallingProcess; import org.jbpm.bpmn2.subprocess.ExceptionServiceProcessSignallingModel; import org.jbpm.bpmn2.subprocess.ExceptionServiceProcessSignallingProcess; import org.jbpm.process.instance.event.listeners.RuleAwareProcessEventListener; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.SignallingTaskHandlerDecorator; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.utils.EventTrackerProcessListener; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.kie.api.event.process.DefaultProcessEventListener; import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.api.event.process.ProcessNodeTriggeredEvent; import org.kie.kogito.Application; import org.kie.kogito.handlers.AlwaysThrowingComponent_throwException__8DA0CD88_0714_43C1_B492_A70FADE42361_Handler; import org.kie.kogito.handlers.ExceptionService_handleException__X_2_Handler; @@ -80,12 +84,15 @@ import org.kie.kogito.internal.process.event.KogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.ProcessInstance; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; +import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIterable; @@ -115,6 +122,7 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); + processInstance.completeWorkItem(workItem.getStringId(), null); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); assertThat(executedNodes).hasSize(1); @@ -127,6 +135,7 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { "start-sub", "Script Task 1", "end-sub"); + } @Test @@ -148,14 +157,8 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new TestWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { throw new MyError(); - - } - - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.abortWorkItem(workItem.getStringId()); } }); @@ -233,6 +236,12 @@ public void testErrorBoundaryEventOnTask() throws Exception { kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/error/BPMN2-ErrorBoundaryEventOnTask.bpmn2"); TestWorkItemHandler handler = new TestWorkItemHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); + kruntime.getKieRuntime().addEventListener(new DefaultProcessEventListener() { + @Override + public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { + System.out.println(event); + } + }); KogitoProcessInstance processInstance = kruntime.startProcess("ErrorBoundaryEventOnTask"); @@ -244,7 +253,7 @@ public void testErrorBoundaryEventOnTask() throws Exception { workItem = workItems.get(1); } - kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), null); + kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), emptyMap()); assertProcessInstanceFinished(processInstance, kruntime); assertProcessInstanceAborted(processInstance); assertNodeTriggered(processInstance.getStringId(), "start", "split", "User Task", "User task error attached", "error end event"); @@ -256,7 +265,7 @@ public void testErrorBoundaryEventOnServiceTask() throws Exception { Application app = ProcessTestHelper.newApplication(); EventTrackerProcessListener listener = new EventTrackerProcessListener(); ProcessTestHelper.registerProcessEventListener(app, listener); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.objects.HelloService_helloException_ServiceTask_2_Handler", new HelloService_helloException_ServiceTask_2_Handler()); @@ -332,15 +341,16 @@ public void testCatchErrorBoundaryEventOnTask() throws Exception { kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", new TestWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { if (workItem.getParameter("ActorId").equals("mary")) { throw new MyError(); } + return Optional.empty(); } @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.abortWorkItem(workItem.getStringId()); + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + return Optional.empty(); } }); @@ -349,7 +359,7 @@ public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager assertProcessInstanceActive(processInstance); assertNodeTriggered(processInstance.getStringId(), "start", "split", "User Task", "User task error attached", - "Script Task", "error1", "error2"); + "Script Task", "error2"); } @@ -364,6 +374,7 @@ public void testErrorSignallingExceptionServiceTask() throws Exception { caughtEventObjectHolder[0] = null; ExceptionService.setCaughtEventObjectHolder(caughtEventObjectHolder); + ProcessTestHelper.registerHandler(app, "Human Task", new TestWorkItemHandler()); ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.objects.ExceptionService_throwException__3_Handler", signallingTaskWrapper); ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.objects.ExceptionService_handleException__X_2_Handler", new ExceptionService_handleException__X_2_Handler()); org.kie.kogito.process.Process definition = ExceptionServiceProcessErrorSignallingProcess.newProcess(app); @@ -373,7 +384,7 @@ public void testErrorSignallingExceptionServiceTask() throws Exception { org.kie.kogito.process.ProcessInstance instance = definition.createInstance(model); instance.start(); - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "john"); + ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap()); assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ABORTED); assertThat(caughtEventObjectHolder[0] != null && caughtEventObjectHolder[0] instanceof KogitoWorkItem).withFailMessage("Event was not passed to Event Subprocess.").isTrue(); } @@ -389,6 +400,7 @@ public void testSignallingExceptionServiceTask() throws Exception { ExceptionService.setCaughtEventObjectHolder(caughtEventObjectHolder); Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new TestWorkItemHandler()); ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.objects.ExceptionService_throwException__2_Handler", signallingTaskWrapper); ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.objects.ExceptionService_handleException__X_2_Handler", new ExceptionService_handleException__X_2_Handler()); org.kie.kogito.process.Process definition = ExceptionServiceProcessSignallingProcess.newProcess(app); @@ -606,20 +618,16 @@ public void testErrorVariable() throws Exception { assertThat(instance.status()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); } - class ExceptionWorkItemHandler implements KogitoWorkItemHandler { + class ExceptionWorkItemHandler extends DefaultKogitoWorkItemHandler { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { throw new RuntimeException(); } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - } - } - class WorkItemExecutionErrorWorkItemHandler implements KogitoWorkItemHandler { + class WorkItemExecutionErrorWorkItemHandler extends DefaultKogitoWorkItemHandler { private final String errorCode; @@ -632,13 +640,9 @@ public WorkItemExecutionErrorWorkItemHandler(String errorCode) { } @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { throw new WorkItemExecutionException(errorCode); } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - } - } } diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EscalationEventTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EscalationEventTest.java index f6568f8df9a..3e6a89eb53a 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EscalationEventTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/EscalationEventTest.java @@ -40,6 +40,7 @@ import org.jbpm.bpmn2.escalation.MultiEscalationProcess; import org.jbpm.bpmn2.escalation.TopLevelEscalationModel; import org.jbpm.bpmn2.escalation.TopLevelEscalationProcess; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.test.utils.EventTrackerProcessListener; import org.jbpm.test.utils.ProcessTestHelper; @@ -51,11 +52,12 @@ import org.kie.api.event.process.SignalEvent; import org.kie.api.runtime.process.ProcessInstance; import org.kie.kogito.Application; +import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.impl.Sig; import static org.assertj.core.api.Assertions.assertThat; @@ -109,6 +111,8 @@ public void onSignal(SignalEvent event) { @Test public void testTopLevelEscalation() throws Exception { Application app = ProcessTestHelper.newApplication(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); + ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); List instances = new ArrayList<>(); ProcessTestHelper.registerProcessEventListener(app, new DefaultKogitoProcessEventListener() { @Override @@ -137,7 +141,7 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { }; EventTrackerProcessListener tracker = new EventTrackerProcessListener(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); Application app = ProcessTestHelper.newApplication(); ProcessTestHelper.registerProcessEventListener(app, listener); @@ -215,7 +219,7 @@ public void testEscalationIntermediateThrowEventProcess() { @Test public void testGeneralEscalationBoundaryEventWithTask() throws Exception { - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); Application app = ProcessTestHelper.newApplication(); ProcessTestHelper.registerHandler(app, "Human Task", handler); @@ -236,12 +240,12 @@ public void testGeneralEscalationBoundaryEventWithTask() throws Exception { public void testInterruptingEscalationBoundaryEventOnTask() throws Exception { kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/escalation/BPMN2-EscalationBoundaryEventOnTaskInterrupting.bpmn2"); - TestWorkItemHandler handler = new TestWorkItemHandler(); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); + kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); kruntime.getProcessEventManager().addEventListener(LOGGING_EVENT_LISTENER); KogitoProcessInstance processInstance = kruntime.startProcess("EscalationBoundaryEventOnTaskInterrupting"); - List workItems = handler.getWorkItems(); + List workItems = workItemHandler.getWorkItems(); assertThat(workItems).hasSize(2); KogitoWorkItem workItem = workItems.get(0); @@ -249,7 +253,7 @@ public void testInterruptingEscalationBoundaryEventOnTask() throws Exception { workItem = workItems.get(1); } - kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), null); + kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), Collections.emptyMap(), SecurityPolicy.of("john", Collections.emptyList())); assertProcessInstanceFinished(processInstance, kruntime); } diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/FlowTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/FlowTest.java index 467c1fbf113..ac63c266f8b 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/FlowTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/FlowTest.java @@ -26,6 +26,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.xml.parsers.DocumentBuilderFactory; @@ -91,14 +92,14 @@ import org.jbpm.bpmn2.flow.MultipleGatewaysProcessProcess; import org.jbpm.bpmn2.loop.MultiInstanceLoopCharacteristicsTaskModel; import org.jbpm.bpmn2.loop.MultiInstanceLoopCharacteristicsTaskProcess; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.bpmn2.timer.ParallelSplitWithTimerProcessModel; import org.jbpm.bpmn2.timer.ParallelSplitWithTimerProcessProcess; import org.jbpm.process.core.context.variable.VariableScope; import org.jbpm.process.instance.InternalProcessRuntime; import org.jbpm.process.instance.context.variable.VariableScopeInstance; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.util.NodeLeftCountDownProcessEventListener; import org.jbpm.test.utils.EventTrackerProcessListener; import org.jbpm.test.utils.ProcessTestHelper; @@ -123,11 +124,14 @@ import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.impl.Sig; +import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -532,12 +536,12 @@ public void testInclusiveParallelExclusiveSplitNoLoop() { ProcessTestHelper.registerHandler(app, "testWI", new SystemOutWorkItemHandler()); ProcessTestHelper.registerHandler(app, "testWI2", new SystemOutWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map results = new HashMap<>(); results.put("output1", x); - manager.completeWorkItem(workItem.getStringId(), results); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), results)); } }); final Map nodeInstanceExecutionCounter = new HashMap<>(); @@ -579,12 +583,12 @@ public void testInclusiveParallelExclusiveSplitLoop() { ProcessTestHelper.registerHandler(app, "testWI", new SystemOutWorkItemHandler()); ProcessTestHelper.registerHandler(app, "testWI2", new SystemOutWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map results = new HashMap<>(); results.put("output1", x); - manager.completeWorkItem(workItem.getStringId(), results); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), results)); } }); final Map nodeInstanceExecutionCounter = new HashMap<>(); @@ -627,12 +631,12 @@ public void testInclusiveParallelExclusiveSplitNoLoopAsync() { ProcessTestHelper.registerHandler(app, "testWI", handler); ProcessTestHelper.registerHandler(app, "testWI2", new SystemOutWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map results = new HashMap<>(); results.put("output1", x); - manager.completeWorkItem(workItem.getStringId(), results); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), results)); } }); final Map nodeInstanceExecutionCounter = new HashMap<>(); @@ -687,12 +691,12 @@ public void testInclusiveParallelExclusiveSplitLoopAsync() { ProcessTestHelper.registerHandler(app, "testWI", handler); ProcessTestHelper.registerHandler(app, "testWI2", new SystemOutWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map results = new HashMap<>(); results.put("output1", x); - manager.completeWorkItem(workItem.getStringId(), results); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), results)); } }); final Map nodeInstanceExecutionCounter = new HashMap<>(); @@ -1232,7 +1236,7 @@ public void testMultiInstanceLoopCharacteristicsTaskWithOutputCompletionConditio @Test public void testMultiInstanceLoopCharacteristicsTask() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); org.kie.kogito.process.Process definition = MultiInstanceLoopCharacteristicsTaskProcess.newProcess(app); @@ -1342,22 +1346,19 @@ public void testConditionalFlow() throws Exception { public void testLane() throws Exception { kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/flow/BPMN2-Lane.bpmn2"); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); KogitoProcessInstance processInstance = kruntime.startProcess("Lane"); assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", - workItemHandler); + KogitoWorkItem KogitoWorkItem = workItemHandler.getWorkItem(); assertThat(KogitoWorkItem).isNotNull(); assertThat(KogitoWorkItem.getParameter("ActorId")).isEqualTo("john"); Map results = new HashMap<>(); - ((InternalHumanTaskWorkItem) KogitoWorkItem).setActualOwner("mary"); + ((KogitoWorkItemImpl) KogitoWorkItem).setParameter("ActorId", "mary"); kruntime.getKogitoWorkItemManager().completeWorkItem(KogitoWorkItem.getStringId(), results); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", - workItemHandler); KogitoWorkItem = workItemHandler.getWorkItem(); assertThat(KogitoWorkItem).isNotNull(); assertThat(KogitoWorkItem.getParameter("SwimlaneActorId")).isEqualTo("mary"); diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java index 00c1c45d721..09410070f55 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java @@ -26,6 +26,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -39,8 +40,6 @@ import org.jbpm.bpmn2.event.BoundaryTimerCycleISOProcess; import org.jbpm.bpmn2.event.BoundaryTimerCycleISOVariableModel; import org.jbpm.bpmn2.event.BoundaryTimerCycleISOVariableProcess; -import org.jbpm.bpmn2.handler.ReceiveTaskHandler; -import org.jbpm.bpmn2.handler.SendTaskHandler; import org.jbpm.bpmn2.intermediate.BoundarySignalEventOnTaskModel; import org.jbpm.bpmn2.intermediate.BoundarySignalEventOnTaskProcess; import org.jbpm.bpmn2.intermediate.EventBasedSplit2Model; @@ -94,6 +93,8 @@ import org.jbpm.bpmn2.intermediate.IntermediateThrowEventMessageWithTransformationProcess; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventNoneModel; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventNoneProcess; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventSignalModel; +import org.jbpm.bpmn2.intermediate.IntermediateThrowEventSignalProcess; import org.jbpm.bpmn2.intermediate.LinkEventCompositeProcessModel; import org.jbpm.bpmn2.intermediate.LinkEventCompositeProcessProcess; import org.jbpm.bpmn2.intermediate.SignalBoundaryEventInterruptingModel; @@ -111,9 +112,8 @@ import org.jbpm.bpmn2.loop.MultiInstanceLoopCharacteristicsTaskWithOutputCmpCondSequentialModel; import org.jbpm.bpmn2.loop.MultiInstanceLoopCharacteristicsTaskWithOutputCmpCondSequentialProcess; import org.jbpm.bpmn2.objects.Person; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.bpmn2.objects.TestWorkItemHandler; -import org.jbpm.bpmn2.start.IntermediateThrowEventSignalModel; -import org.jbpm.bpmn2.start.IntermediateThrowEventSignalProcess; import org.jbpm.bpmn2.subprocess.EventSubprocessConditionalModel; import org.jbpm.bpmn2.subprocess.EventSubprocessConditionalProcess; import org.jbpm.bpmn2.subprocess.EventSubprocessMessageModel; @@ -133,8 +133,10 @@ import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingProcess; import org.jbpm.process.core.datatype.impl.type.StringDataType; import org.jbpm.process.instance.event.listeners.RuleAwareProcessEventListener; -import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.DoNothingWorkItemHandler; +import org.jbpm.process.workitem.builtin.ReceiveTaskHandler; +import org.jbpm.process.workitem.builtin.SendTaskHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.util.NodeLeftCountDownProcessEventListener; import org.jbpm.test.util.ProcessCompletedCountDownProcessEventListener; import org.jbpm.test.utils.EventTrackerProcessListener; @@ -149,21 +151,23 @@ import org.kie.api.event.process.ProcessStartedEvent; import org.kie.api.runtime.rule.FactHandle; import org.kie.kogito.Application; -import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.event.impl.MessageProducer; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.EventDescription; import org.kie.kogito.process.NamedDataType; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.impl.Sig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; +import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import static org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT; @@ -201,8 +205,8 @@ public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { @Test public void testBoundaryTimerCycleISO() { Application app = ProcessTestHelper.newApplication(); - NodeLeftCountDownProcessEventListener listener = new NodeLeftCountDownProcessEventListener("Send Update Timer", - 3); + NodeLeftCountDownProcessEventListener listener = new NodeLeftCountDownProcessEventListener("Send Update Timer", 3); + ProcessTestHelper.registerHandler(app, "Human Task", new TestUserTaskWorkItemHandler()); ProcessTestHelper.registerProcessEventListener(app, listener); org.kie.kogito.process.Process definition = BoundaryTimerCycleISOProcess .newProcess(app); @@ -219,6 +223,7 @@ public void testBoundaryTimerCycleISOVariable() { Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener listener = new NodeLeftCountDownProcessEventListener("Send Update Timer", 3); + ProcessTestHelper.registerHandler(app, "Human Task", new TestUserTaskWorkItemHandler()); ProcessTestHelper.registerProcessEventListener(app, listener); org.kie.kogito.process.Process definition = BoundaryTimerCycleISOVariableProcess .newProcess(app); @@ -280,13 +285,10 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { KogitoProcessInstance processInstance = kruntime.startProcess("BoundaryEventWithNonEffectiveSignal"); // outer human work - kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), null); + kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), emptyMap()); kruntime.signalEvent(signal, signal); - // inner human task - kruntime.getKogitoWorkItemManager().completeWorkItem(handler.getWorkItem().getStringId(), null); - assertProcessInstanceFinished(processInstance, kruntime); assertThat(eventAfterNodeLeftTriggered).isTrue(); } @@ -399,7 +401,7 @@ public void testSignalBetweenProcesses() { KogitoWorkItem workItem = handler.getWorkItem(); assertThat(workItem).isNotNull(); - signalSingleProcessInstance.completeWorkItem(workItem.getStringId(), null, SecurityPolicy.of("user", Collections.emptyList())); + signalSingleProcessInstance.completeWorkItem(workItem.getStringId(), null); org.kie.kogito.process.ProcessInstance throwEventSignalProcessInstance = throwEventSignalProcess.createInstance(throwEventSignalProcess.createModel()); throwEventSignalProcessInstance.start(); @@ -587,27 +589,31 @@ public void testEventBasedSplit5() throws Exception { kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(kruntime); + ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); // Yes KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit5"); - assertProcessInstanceActive(processInstance); + assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - receiveTaskHandler.setKnowledgeRuntime(kruntime); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); - receiveTaskHandler.messageReceived("YesMessage", "YesValue"); - assertProcessInstanceFinished(processInstance, kruntime); - receiveTaskHandler.messageReceived("NoMessage", "NoValue"); + + receiveTaskHandler.getWorkItemId().stream().findFirst().ifPresent(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "YesValue"))); + + assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + + receiveTaskHandler.getWorkItemId().forEach(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "NoValue"))); + kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - receiveTaskHandler.setKnowledgeRuntime(kruntime); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); // No processInstance = kruntime.startProcess("EventBasedSplit5"); - receiveTaskHandler.messageReceived("NoMessage", "NoValue"); - assertProcessInstanceFinished(processInstance, kruntime); - receiveTaskHandler.messageReceived("YesMessage", "YesValue"); + receiveTaskHandler.getWorkItemId().stream().findFirst().ifPresent(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "NoValue"))); + + assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); + + receiveTaskHandler.getWorkItemId().forEach(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "YesValue"))); } @@ -795,7 +801,7 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { public void testEventSubprocessMessage() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); List executednodes = new ArrayList<>(); KogitoProcessEventListener listener = new DefaultKogitoProcessEventListener() { @@ -934,7 +940,7 @@ public void afterNodeLeft(ProcessNodeLeftEvent event) { ProcessTestHelper.registerProcessEventListener(app, listener); EventTrackerProcessListener trackerListener = new EventTrackerProcessListener(); ProcessTestHelper.registerProcessEventListener(app, trackerListener); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process definition = EventSubprocessConditionalProcess @@ -1753,7 +1759,6 @@ public void testIntermediateCatchEventSignalAndBoundarySignalEvent() throws Exce KogitoProcessInstance processInstance = kruntime.startProcess("BoundaryEventWithSignals"); assertProcessInstanceActive(processInstance); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); // now signal process instance kruntime.signalEvent("moveon", "", processInstance.getStringId()); assertProcessInstanceActive(processInstance); @@ -1792,6 +1797,8 @@ public void testSignalIntermediateThrowEventWithTransformation() throws Exceptio @Test public void testSignalBoundaryEventWithTransformation() throws Exception { Application application = ProcessTestHelper.newApplication(); + TestWorkItemHandler handler = new TestWorkItemHandler(); + ProcessTestHelper.registerHandler(application, "Human Task", handler); org.kie.kogito.process.Process processBoundary = BoundarySignalEventOnTaskWithTransformationProcess .newProcess(application); org.kie.kogito.process.Process processIntermediate = IntermediateThrowEventSignalProcess @@ -2008,7 +2015,7 @@ public void testMultiInstanceLoopBoundaryTimer() throws Exception { Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("timer", 3); ProcessTestHelper.registerProcessEventListener(app, countDownListener); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); org.kie.kogito.process.Process definition = MultiInstanceLoopBoundaryTimerProcess.newProcess(app); @@ -2032,7 +2039,7 @@ public void testMultiInstanceLoopBoundaryTimer() throws Exception { @Test public void testMultiInstanceLoopCharacteristicsProcessSequential() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); org.kie.kogito.process.Process definition = MultiInstanceLoopCharacteristicsProcessSequentialProcess.newProcess(app); @@ -2076,7 +2083,7 @@ public void testMultiInstanceLoopCharacteristicsProcessWithOutputAndScripts() th @Test public void testMultiInstanceLoopCharacteristicsTask() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); org.kie.kogito.process.Process definition = MultiInstanceLoopCharacteristicsTaskProcess.newProcess(app); @@ -2101,7 +2108,7 @@ public void testMultiInstanceLoopCharacteristicsTask() throws Exception { @Test public void testMultiInstanceLoopCharacteristicsTaskSequential() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); org.kie.kogito.process.Process definition = MultiInstanceLoopCharacteristicsTaskSequentialProcess.newProcess(app); @@ -2133,7 +2140,7 @@ public void testMultiInstanceLoopCharacteristicsTaskSequential() throws Exceptio @Test public void testMultiInstanceLoopCharacteristicsTaskWithOutputCmpCondSequential() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler handler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler handler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", handler); org.kie.kogito.process.Process definition = @@ -2280,20 +2287,15 @@ public void testThrowIntermediateSignalWithExternalScope() throws Exception { kruntime = createKogitoProcessRuntime( "org/jbpm/bpmn2/intermediate/BPMN2-IntermediateThrowEventExternalScope.bpmn2"); TestWorkItemHandler handler = new TestWorkItemHandler(); - KogitoWorkItemHandler externalHandler = new KogitoWorkItemHandler() { + KogitoWorkItemHandler externalHandler = new DefaultKogitoWorkItemHandler() { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { String signal = (String) workItem.getParameter("Signal"); kruntime.signalEvent(signal, null); - - manager.completeWorkItem(workItem.getStringId(), null); - + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), Collections.emptyMap())); } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - } }; kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", handler); diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/SLAComplianceTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/SLAComplianceTest.java index bfe578dde3b..eebe4330773 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/SLAComplianceTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/SLAComplianceTest.java @@ -32,7 +32,7 @@ import org.jbpm.bpmn2.sla.UserTaskWithSLAOnTaskModel; import org.jbpm.bpmn2.sla.UserTaskWithSLAOnTaskProcess; import org.jbpm.bpmn2.sla.UserTaskWithSLAProcess; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Test; import org.kie.api.event.process.SLAViolatedEvent; @@ -42,8 +42,8 @@ import org.kie.kogito.internal.process.event.KogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.impl.AbstractProcessInstance; import org.kie.kogito.process.impl.Sig; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java index 86bfb76e445..78088212334 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StandaloneBPMNProcessTest.java @@ -72,8 +72,6 @@ import org.jbpm.bpmn2.flow.SubProcessProcess; import org.jbpm.bpmn2.flow.UserTaskModel; import org.jbpm.bpmn2.flow.UserTaskProcess; -import org.jbpm.bpmn2.handler.ReceiveTaskHandler; -import org.jbpm.bpmn2.handler.SendTaskHandler; import org.jbpm.bpmn2.intermediate.EventBasedSplit2Model; import org.jbpm.bpmn2.intermediate.EventBasedSplit2Process; import org.jbpm.bpmn2.intermediate.EventBasedSplit4Model; @@ -93,7 +91,7 @@ import org.jbpm.bpmn2.intermediate.IntermediateThrowEventSignalModel; import org.jbpm.bpmn2.intermediate.IntermediateThrowEventSignalProcess; import org.jbpm.bpmn2.objects.Person; -import org.jbpm.bpmn2.objects.TestWorkItemHandler; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.bpmn2.start.MessageStartModel; import org.jbpm.bpmn2.start.MessageStartProcess; import org.jbpm.bpmn2.start.SignalStartModel; @@ -110,9 +108,10 @@ import org.jbpm.bpmn2.timer.TimerBoundaryEventDurationProcess; import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingModel; import org.jbpm.bpmn2.timer.TimerBoundaryEventInterruptingProcess; -import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; +import org.jbpm.process.workitem.builtin.DoNothingWorkItemHandler; +import org.jbpm.process.workitem.builtin.ReceiveTaskHandler; +import org.jbpm.process.workitem.builtin.SendTaskHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.util.NodeLeftCountDownProcessEventListener; import org.jbpm.test.util.ProcessCompletedCountDownProcessEventListener; import org.jbpm.test.utils.ProcessTestHelper; @@ -127,9 +126,10 @@ import org.kie.kogito.event.impl.MessageProducer; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.impl.Sig; +import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; import org.w3c.dom.Document; import static org.assertj.core.api.Assertions.assertThat; @@ -239,7 +239,7 @@ public void testEvaluationProcess3() { @Test public void testUserTask() { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process processDefinition = UserTaskProcess.newProcess(app); UserTaskModel model = processDefinition.createModel(); @@ -258,18 +258,16 @@ public void testUserTask() { public void testLane() throws Exception { kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/flow/BPMN2-Lane.bpmn2"); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); KogitoProcessInstance processInstance = kruntime.startProcess("Lane"); assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); KogitoWorkItem workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("ActorId")).isEqualTo("john"); Map results = new HashMap<>(); - ((InternalHumanTaskWorkItem) workItem).setActualOwner("mary"); + ((KogitoWorkItemImpl) workItem).setParameter("ActorId", "mary"); kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(), results); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); workItem = workItemHandler.getWorkItem(); assertThat(workItem).isNotNull(); assertThat(workItem.getParameter("SwimlaneActorId")).isEqualTo("mary"); @@ -460,27 +458,31 @@ public void testEventBasedSplit5() throws Exception { kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(kruntime); + ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); // Yes KogitoProcessInstance processInstance = kruntime.startProcess("EventBasedSplit5"); assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - receiveTaskHandler.setKnowledgeRuntime(kruntime); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); - receiveTaskHandler.messageReceived("YesMessage", "YesValue"); + + receiveTaskHandler.getWorkItemId().stream().findFirst().ifPresent(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "YesValue"))); + assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); - receiveTaskHandler.messageReceived("NoMessage", "NoValue"); + + receiveTaskHandler.getWorkItemId().forEach(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "NoValue"))); + kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); - receiveTaskHandler.setKnowledgeRuntime(kruntime); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); // No processInstance = kruntime.startProcess("EventBasedSplit5"); - receiveTaskHandler.messageReceived("NoMessage", "NoValue"); + receiveTaskHandler.getWorkItemId().stream().findFirst().ifPresent(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "NoValue"))); + assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); - receiveTaskHandler.messageReceived("YesMessage", "YesValue"); + + receiveTaskHandler.getWorkItemId().stream().findFirst().ifPresent(id -> kruntime.getKogitoWorkItemManager().completeWorkItem(id, Map.of("Message", "YesValue"))); } @Test @@ -558,7 +560,8 @@ public void testTimerBoundaryEvent() throws Exception { public void testTimerBoundaryEventInterrupting() { Application app = ProcessTestHelper.newApplication(); NodeLeftCountDownProcessEventListener countDownListener = new NodeLeftCountDownProcessEventListener("TimerEvent", 1); - ProcessCompletedCountDownProcessEventListener processEventListener = new ProcessCompletedCountDownProcessEventListener(); + ProcessCompletedCountDownProcessEventListener processEventListener = + new ProcessCompletedCountDownProcessEventListener(); ProcessTestHelper.registerHandler(app, "MyTask", new DoNothingWorkItemHandler()); ProcessTestHelper.registerProcessEventListener(app, processEventListener); ProcessTestHelper.registerProcessEventListener(app, countDownListener); @@ -567,6 +570,7 @@ public void testTimerBoundaryEventInterrupting() { org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); logger.debug("Starting process instance"); instance.start(); + assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); processEventListener.waitTillCompleted(); @@ -579,7 +583,7 @@ public void testTimerBoundaryEventInterrupting() { public void testAdHocSubProcess() throws Exception { kruntime = createKogitoProcessRuntime("BPMN2-AdHocSubProcess.bpmn2"); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); KogitoProcessInstance processInstance = kruntime.startProcess("AdHocSubProcess"); assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); @@ -601,6 +605,7 @@ public void testAdHocSubProcessAutoComplete() throws Exception { // this autocomplete when we detect // getActivityInstanceAttribute("numberOfActiveInstances") == 0 Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new TestUserTaskWorkItemHandler()); org.kie.kogito.process.Process definition = AdHocSubProcessAutoCompleteProcess.newProcess(app); org.kie.kogito.process.ProcessInstance instance = definition.createInstance(definition.createModel()); @@ -619,6 +624,7 @@ public void testAdHocSubProcessAutoCompleteExpression() throws Exception { // this autocomplete when we detect // getActivityInstanceAttribute("numberOfActiveInstances") == 0 Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new TestUserTaskWorkItemHandler()); org.kie.kogito.process.Process definition = AdHocSubProcessAutoCompleteExpressionProcess.newProcess(app); AdHocSubProcessAutoCompleteExpressionModel model = definition.createModel(); model.setCounter(3); @@ -638,6 +644,7 @@ public void testAdHocTerminateEndEvent() throws Exception { // this autocomplete when we detect // terminate end event within adhoc process the adhoc should finish Application app = ProcessTestHelper.newApplication(); + ProcessTestHelper.registerHandler(app, "Human Task", new TestUserTaskWorkItemHandler()); org.kie.kogito.process.Process definition = AdHocTerminateEndEventProcess.newProcess(app); AdHocTerminateEndEventModel model = definition.createModel(); model.setComplete(false); @@ -752,17 +759,14 @@ public void testSendTask() { @Test public void testReceiveTask() throws Exception { Application app = ProcessTestHelper.newApplication(); - kruntime = createKogitoProcessRuntime("org/jbpm/bpmn2/task/BPMN2-ReceiveTask.bpmn2"); - ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(kruntime); + ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(); ProcessTestHelper.registerHandler(app, "Receive Task", receiveTaskHandler); org.kie.kogito.process.Process processDefinition = ReceiveTaskProcess.newProcess(app); ReceiveTaskModel model = processDefinition.createModel(); org.kie.kogito.process.ProcessInstance instance = processDefinition.createInstance(model); instance.start(); assertThat(instance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); - receiveTaskHandler.setKnowledgeRuntime(kruntime); - receiveTaskHandler.messageReceived("HelloMessage", "Hello john!"); - ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(), "john"); + ProcessTestHelper.completeWorkItem(instance, Collections.singletonMap("Message", "Hello john!"), "john"); assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED); } diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StartEventTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StartEventTest.java index b79e499d85a..b679fa3caa1 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StartEventTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/StartEventTest.java @@ -53,7 +53,7 @@ import org.jbpm.bpmn2.start.TimerStartISOProcess; import org.jbpm.bpmn2.start.TimerStartModel; import org.jbpm.bpmn2.start.TimerStartProcess; -import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; +import org.jbpm.process.workitem.builtin.SystemOutWorkItemHandler; import org.jbpm.test.util.NodeLeftCountDownProcessEventListener; import org.jbpm.test.utils.EventTrackerProcessListener; import org.jbpm.test.utils.ProcessTestHelper; @@ -66,7 +66,7 @@ import org.kie.kogito.Application; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.Process; import org.kie.kogito.process.impl.Sig; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/VariableTagsTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/VariableTagsTest.java index db63be23c25..222773ce4cf 100644 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/VariableTagsTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/VariableTagsTest.java @@ -39,11 +39,12 @@ import org.kie.api.event.process.ProcessVariableChangedEvent; import org.kie.kogito.Application; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.VariableViolationException; import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -143,7 +144,9 @@ public void beforeVariableChanged(ProcessVariableChangedEvent event) { @Test public void testRequiredVariableFiltering() { - List processes = BpmnProcess.from(new ClassPathResource("org/jbpm/bpmn2/tags/BPMN2-ApprovalWithCustomVariableTags.bpmn2")); + DefaultWorkItemHandlerConfig config = new DefaultWorkItemHandlerConfig(); + config.register("Human Task", new TestWorkItemHandler()); + List processes = BpmnProcess.from(config, new ClassPathResource("org/jbpm/bpmn2/tags/BPMN2-ApprovalWithCustomVariableTags.bpmn2")); BpmnProcess process = processes.get(0); Map params = new HashMap<>(); params.put("approver", "john"); diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/MultipleProcessesPerThreadTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/MultipleProcessesPerThreadTest.java index 1ce7101a0a4..7d1c7267f21 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/MultipleProcessesPerThreadTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/MultipleProcessesPerThreadTest.java @@ -38,7 +38,7 @@ import org.kie.internal.builder.KnowledgeBuilderFactory; import org.kie.internal.io.ResourceFactory; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/OneProcessPerThreadTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/OneProcessPerThreadTest.java index 22e910ca1d7..b323fab7068 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/OneProcessPerThreadTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/concurrency/OneProcessPerThreadTest.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -33,9 +34,11 @@ import org.kie.internal.builder.KnowledgeBuilderFactory; import org.kie.internal.io.ResourceFactory; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,14 +65,15 @@ public void testMultiThreadProcessInstanceWorkItem() throws Exception { KogitoProcessRuntime kruntime = InternalProcessRuntime.asKogitoProcessRuntime(kbase.newKieSession()); - kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Log", new KogitoWorkItemHandler() { - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Log", new DefaultKogitoWorkItemHandler() { + + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Long threadId = (Long) workItem.getParameter("id"); workItems.put(workItem.getProcessInstanceStringId(), threadId); + return Optional.empty(); } - public void abortWorkItem(KogitoWorkItem arg0, KogitoWorkItemManager arg1) { - } }); startThreads(kruntime); diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/ErrornousWorkItemHandler.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/ErrornousWorkItemHandler.java index 96f91807839..7d9ae570e14 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/ErrornousWorkItemHandler.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/ErrornousWorkItemHandler.java @@ -18,14 +18,18 @@ */ package org.jbpm.bpmn2.handler; +import java.util.Optional; + import org.kie.api.runtime.process.ProcessWorkItemHandlerException; import org.kie.api.runtime.process.ProcessWorkItemHandlerException.HandlingStrategy; import org.kie.api.runtime.process.WorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public class ErrornousWorkItemHandler implements KogitoWorkItemHandler { +public class ErrornousWorkItemHandler extends DefaultKogitoWorkItemHandler { private String processId; private HandlingStrategy strategy; @@ -39,25 +43,23 @@ public ErrornousWorkItemHandler(String processId, HandlingStrategy strategy) { } @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { this.workItem = workItem; if (processId != null && strategy != null) { if (workItem.getParameter("isCheckedCheckbox") != null) { - manager.completeWorkItem(workItem.getStringId(), workItem.getParameters()); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), workItem.getParameters())); } else { - throw new ProcessWorkItemHandlerException(processId, strategy, new RuntimeException("On purpose")); } } - - manager.completeWorkItem(workItem.getStringId(), null); + return Optional.empty(); } @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { this.workItem = workItem; - + return Optional.empty(); } public WorkItem getWorkItem() { diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerWrapperTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerWrapperTest.java index 9668f485b03..c382b2c2221 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerWrapperTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerWrapperTest.java @@ -21,9 +21,10 @@ import java.util.ArrayList; import java.util.List; -import org.jbpm.bpmn2.handler.LoggingTaskHandlerDecorator.InputParameter; import org.jbpm.bpmn2.subprocess.ExceptionThrowingServiceProcessModel; import org.jbpm.bpmn2.subprocess.ExceptionThrowingServiceProcessProcess; +import org.jbpm.process.workitem.builtin.LoggingTaskHandlerDecorator; +import org.jbpm.process.workitem.builtin.LoggingTaskHandlerDecorator.InputParameter; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Test; import org.kie.kogito.Application; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/WorkItemHandlerExceptionHandlingTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/WorkItemHandlerExceptionHandlingTest.java index 4c7ce91ef23..5ec4f796ff2 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/WorkItemHandlerExceptionHandlingTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/handler/WorkItemHandlerExceptionHandlingTest.java @@ -38,7 +38,7 @@ import org.kie.kogito.correlation.CompositeCorrelation; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.Processes; diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/structureref/StructureRefTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/structureref/StructureRefTest.java index 479720a0cbe..1e8e3a73969 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/structureref/StructureRefTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/structureref/StructureRefTest.java @@ -35,14 +35,14 @@ import org.jbpm.bpmn2.flow.ObjectStructureRefModel; import org.jbpm.bpmn2.flow.ObjectStructureRefProcess; import org.jbpm.bpmn2.objects.Person; -import org.jbpm.bpmn2.objects.TestWorkItemHandler; +import org.jbpm.bpmn2.objects.TestUserTaskWorkItemHandler; import org.jbpm.process.core.datatype.impl.coverter.TypeConverterRegistry; import org.jbpm.test.utils.ProcessTestHelper; import org.junit.jupiter.api.Test; import org.kie.kogito.Application; +import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.process.bpmn2.BpmnVariables; -import org.kie.kogito.process.workitem.Policies; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; @@ -57,7 +57,7 @@ public class StructureRefTest extends JbpmBpmn2TestCase { public void testStringStructureRef() throws Exception { kruntime = createKogitoProcessRuntime("BPMN2-StringStructureRef.bpmn2"); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); KogitoProcessInstance processInstance = kruntime.startProcess("StructureRef"); @@ -68,7 +68,7 @@ public void testStringStructureRef() throws Exception { kruntime.getKogitoWorkItemManager().completeWorkItem( workItemHandler.getWorkItem().getStringId(), res, - Policies.of("john")); + SecurityPolicy.of("john", Collections.emptyList())); assertProcessInstanceCompleted(processInstance.getStringId(), kruntime); } @@ -77,7 +77,7 @@ public void testStringStructureRef() throws Exception { public void testBooleanStructureRef() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process definition = BooleanStructureRefProcess.newProcess(app); @@ -95,7 +95,7 @@ public void testIntegerStructureRef() throws Exception { String value = "25"; Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); IntegerStructureRefProcess definition = (IntegerStructureRefProcess) IntegerStructureRefProcess.newProcess(app); @@ -116,7 +116,7 @@ public void testFloatStructureRef() throws Exception { String value = "5.5"; Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); FloatStructureRefProcess definition = (FloatStructureRefProcess) FloatStructureRefProcess.newProcess(app); @@ -147,7 +147,7 @@ public void testObjectStructureRef() throws Exception { String value = "1john"; Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); ObjectStructureRefProcess definition = (ObjectStructureRefProcess) ObjectStructureRefProcess.newProcess(app); @@ -168,7 +168,7 @@ public void testDefaultObjectStructureRef() throws Exception { String value = "simple text for testing"; Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); DefaultObjectStructureRefProcess definition = (DefaultObjectStructureRefProcess) DefaultObjectStructureRefProcess.newProcess(app); @@ -188,7 +188,7 @@ public void testDefaultObjectStructureRef() throws Exception { public void testNotExistingVarBooleanStructureRefOnStart() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process definition = BooleanStructureRefProcess.newProcess(app); org.kie.kogito.Model model = BpmnVariables.create(Collections.singletonMap("not existing", "invalid boolean")); @@ -201,7 +201,7 @@ public void testNotExistingVarBooleanStructureRefOnStart() throws Exception { public void testInvalidBooleanStructureRefOnStart() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process definition = BooleanStructureRefProcess.newProcess(app); org.kie.kogito.Model model = BpmnVariables.create(Collections.singletonMap("test", "invalid boolean")); @@ -215,7 +215,7 @@ public void testInvalidBooleanStructureRefOnStart() throws Exception { public void testInvalidBooleanStructureRefOnWIComplete() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); IntegerStructureRefProcess definition = (IntegerStructureRefProcess) IntegerStructureRefProcess.newProcess(app); @@ -240,7 +240,7 @@ public void testInvalidBooleanStructureRefOnWIComplete() throws Exception { public void testInvalidBooleanStructureRefOnStartVerifyErrorMsg() throws Exception { Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); org.kie.kogito.process.Process definition = BooleanStructureRefProcess.newProcess(app); org.kie.kogito.Model model = BpmnVariables.create(Collections.singletonMap("test", "invalid boolean")); @@ -258,7 +258,7 @@ public void testNotExistingBooleanStructureRefOnWIComplete() throws Exception { String wrongDataOutput = "not existing"; Application app = ProcessTestHelper.newApplication(); - TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); + TestUserTaskWorkItemHandler workItemHandler = new TestUserTaskWorkItemHandler(); ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler); IntegerStructureRefProcess definition = (IntegerStructureRefProcess) IntegerStructureRefProcess.newProcess(app); diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java index 1b6cfbdeca1..1c111d88d90 100644 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java @@ -18,6 +18,7 @@ */ package org.jbpm.test.utils; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -36,7 +37,7 @@ import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.internal.process.event.KogitoEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.WorkItem; @@ -98,11 +99,23 @@ public static void completeWorkItem(ProcessInstance processInst } public static void completeWorkItem(ProcessInstance processInstance, Map outputVars, Consumer workItem, String userName, String... groups) { - List workItems = processInstance.workItems(SecurityPolicy.of(userName, Arrays.asList(groups))); - workItems.stream().findFirst().ifPresent(e -> { - workItem.accept(e); + List workItems = new ArrayList<>(); + if (userName != null) { + workItems.addAll(processInstance.workItems(SecurityPolicy.of(userName, Arrays.asList(groups)))); + } else { + workItems.addAll(processInstance.workItems()); + } + if (workItems.isEmpty()) { + return; + } + WorkItem e = workItems.get(0); + workItem.accept(e); + if (userName != null) { processInstance.completeWorkItem(e.getId(), outputVars, SecurityPolicy.of(userName, Arrays.asList(groups))); - }); + } else { + processInstance.completeWorkItem(e.getId(), outputVars); + } + } public static WorkItem findWorkItem(ProcessInstance processInstance, String userName) { diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ReceiveTaskTestHandler.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ReceiveTaskTestHandler.java index b05f6b16e62..74692fe7928 100644 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ReceiveTaskTestHandler.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ReceiveTaskTestHandler.java @@ -20,24 +20,21 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public class ReceiveTaskTestHandler implements KogitoWorkItemHandler { +public class ReceiveTaskTestHandler extends DefaultKogitoWorkItemHandler { // TODO: use correlation instead of message id private Map waiting = new HashMap<>(); private KogitoWorkItemManager manager; - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - this.manager = manager; - String messageId = (String) workItem.getParameter("MessageId"); - waiting.put(messageId, workItem.getStringId()); - } - public void messageReceived(String messageId, Object message) { String workItemId = waiting.get(messageId); if (workItemId == null) { @@ -48,9 +45,19 @@ public void messageReceived(String messageId, Object message) { manager.completeWorkItem(workItemId, results); } - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + this.manager = manager; + String messageId = (String) workItem.getParameter("MessageId"); + waiting.put(messageId, workItem.getStringId()); + return Optional.empty(); + } + + @Override + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { String messageId = (String) workItem.getParameter("MessageId"); waiting.remove(messageId); + return Optional.empty(); } } diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/SendTaskTestHandler.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/SendTaskTestHandler.java index d6b7b92eeed..1134e303131 100644 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/SendTaskTestHandler.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/SendTaskTestHandler.java @@ -18,30 +18,31 @@ */ package org.jbpm.test.utils; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import java.util.Collections; +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SendTaskTestHandler implements KogitoWorkItemHandler { +public class SendTaskTestHandler extends DefaultKogitoWorkItemHandler { private static final Logger logger = LoggerFactory.getLogger(SendTaskTestHandler.class); private String lastMessage; private boolean sent = false; - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { String message = (String) workItem.getParameter("Message"); this.lastMessage = message; this.sent = true; logger.debug("Sending message: {}", message); - manager.completeWorkItem(workItem.getStringId(), null); - - } - - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - // Do nothing, cannot be aborted + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), Collections.emptyMap())); } public String lastMessage() { diff --git a/jbpm/jbpm-tools/jbpm-tools-maven-plugin/pom.xml b/jbpm/jbpm-tools/jbpm-tools-maven-plugin/pom.xml index 39420a95e30..3a159e40323 100644 --- a/jbpm/jbpm-tools/jbpm-tools-maven-plugin/pom.xml +++ b/jbpm/jbpm-tools/jbpm-tools-maven-plugin/pom.xml @@ -96,11 +96,6 @@ google-collections test - - org.slf4j - slf4j-simple - test - diff --git a/jbpm/jbpm-usertask/pom.xml b/jbpm/jbpm-usertask/pom.xml new file mode 100644 index 00000000000..3adb16a9ff0 --- /dev/null +++ b/jbpm/jbpm-usertask/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + jbpm + org.kie.kogito + 999-SNAPSHOT + + + jbpm-usertask + + + Kogito :: jBPM :: User Task + jBPM User Task + + + UTF-8 + org.kie.kogito.jbpm.usertask + + + + + org.kie.kogito + kogito-api + + + org.kie.kogito + process-workitems + + + org.kie.kogito + kogito-services + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + ch.qos.logback + logback-classic + test + + + org.assertj + assertj-core + test + + + + + + + org.kie.kogito + kogito-kie-bom + ${project.version} + pom + import + + + + diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Policies.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/Policies.java similarity index 84% rename from api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Policies.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/Policies.java index 2fa2e88f72c..fb714039435 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/Policies.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/Policies.java @@ -16,22 +16,22 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.process.workitem; +package org.kie.kogito.jbpm.usertask.handler; import java.util.Collection; import java.util.Collections; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; +import org.kie.kogito.internal.process.workitem.Policy; public class Policies { - @SuppressWarnings("unchecked") - public static Policy[] of(String user, Collection roles) { + public static Policy[] of(String user, Collection roles) { return user == null ? new Policy[0] : new Policy[] { SecurityPolicy.of(IdentityProviders.of(user, roles)) }; } - public static Policy[] of(String user) { + public static Policy[] of(String user) { return of(user, Collections.emptyList()); } diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java new file mode 100644 index 00000000000..4fb06024d3e --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandler.java @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.jbpm.usertask.handler; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.kie.kogito.auth.SecurityPolicy; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCycle; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCyclePhase; +import org.kie.kogito.internal.process.workitem.WorkItemPhaseState; +import org.kie.kogito.internal.process.workitem.WorkItemTerminationType; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.InternalKogitoWorkItem; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; +import org.kie.kogito.process.workitems.impl.DefaultWorkItemLifeCycle; +import org.kie.kogito.process.workitems.impl.DefaultWorkItemLifeCyclePhase; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTasks; +import org.kie.kogito.usertask.impl.DefaultUserTaskInstance; + +import static java.util.Collections.emptyMap; +import static java.util.Optional.ofNullable; + +/** + * Default Work Item handler based on the standard life cycle + */ +public class UserTaskKogitoWorkItemHandler extends DefaultKogitoWorkItemHandler { + + private static String UT_SEPARATOR = System.getProperty("org.jbpm.ht.user.separator", ","); + + public static final WorkItemPhaseState INACTIVE = WorkItemPhaseState.initialized(); + public static final WorkItemPhaseState COMPLETED = WorkItemPhaseState.of("Completed", WorkItemTerminationType.COMPLETE); + public static final WorkItemPhaseState ABORTED = WorkItemPhaseState.of("Aborted", WorkItemTerminationType.ABORT); + public static final WorkItemPhaseState ACTIVATED = WorkItemPhaseState.of("Activated"); + public static final WorkItemPhaseState RESERVED = WorkItemPhaseState.of("Reserved"); + + public static final WorkItemLifeCyclePhase TRANSITION_RESERVED_COMPLETE = + new DefaultWorkItemLifeCyclePhase("complete", RESERVED, COMPLETED, UserTaskKogitoWorkItemHandler::userTaskCompleteWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_ACTIVATED_COMPLETE = + new DefaultWorkItemLifeCyclePhase("complete", ACTIVATED, COMPLETED, UserTaskKogitoWorkItemHandler::userTaskCompleteFromActiveWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_RESERVED_ABORT = + new DefaultWorkItemLifeCyclePhase("abort", RESERVED, ABORTED, UserTaskKogitoWorkItemHandler::userTaskAbortWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_ACTIVATED_ABORT = + new DefaultWorkItemLifeCyclePhase("abort", ACTIVATED, ABORTED, UserTaskKogitoWorkItemHandler::userTaskAbortWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_ACTIVATED_CLAIM = + new DefaultWorkItemLifeCyclePhase("claim", ACTIVATED, RESERVED, UserTaskKogitoWorkItemHandler::userTaskClaimWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_CREATED_ACTIVE = + new DefaultWorkItemLifeCyclePhase("activate", INACTIVE, ACTIVATED, UserTaskKogitoWorkItemHandler::userTaskActivateWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_RESERVED_RELEASE = + new DefaultWorkItemLifeCyclePhase("release", RESERVED, ACTIVATED, UserTaskKogitoWorkItemHandler::userTaskReleaseWorkItemHandler); + public static final WorkItemLifeCyclePhase TRANSITION_ACTIVATED_COMPLETED = + new DefaultWorkItemLifeCyclePhase("skip", ACTIVATED, COMPLETED, UserTaskKogitoWorkItemHandler::userTaskCompleteWorkItemHandler); + + private static final String DESCRIPTION = "Description"; + private static final String PRIORITY = "Priority"; + private static final String TASK_NAME = "TaskName"; + private static final String ACTOR_ID = "ActorId"; + private static final String GROUP_ID = "GroupId"; + private static final String BUSINESSADMINISTRATOR_ID = "BusinessAdministratorId"; + private static final String BUSINESSADMINISTRATOR_GROUP_ID = "BusinessAdministratorGroupId"; + private static final String EXCLUDED_OWNER_ID = "ExcludedOwnerId"; + + @Override + public String getName() { + return "Human Task"; + } + + @Override + public WorkItemLifeCycle initialize() { + return new DefaultWorkItemLifeCycle( + TRANSITION_CREATED_ACTIVE, + TRANSITION_ACTIVATED_CLAIM, + TRANSITION_ACTIVATED_ABORT, + TRANSITION_ACTIVATED_COMPLETE, + TRANSITION_RESERVED_RELEASE, + TRANSITION_RESERVED_ABORT, + TRANSITION_RESERVED_COMPLETE, + TRANSITION_ACTIVATED_COMPLETED); + } + + @Override + public WorkItemTransition startingTransition(Map data, Policy... policies) { + return workItemLifeCycle.newTransition("activate", null, data, policies); + } + + @Override + public WorkItemTransition abortTransition(String phaseStatus, Policy... policies) { + return workItemLifeCycle.newTransition("abort", phaseStatus, emptyMap(), policies); + } + + @Override + public WorkItemTransition completeTransition(String phaseStatus, Map data, Policy... policies) { + return workItemLifeCycle.newTransition("complete", phaseStatus, data, policies); + } + + static public Optional userTaskActivateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + UserTasks userTasks = handler.getApplication().get(UserTasks.class); + + Object priority = workItem.getParameter(PRIORITY); + Integer priorityInteger = null; + if (priority instanceof String priorityString) { + priorityInteger = Integer.parseInt((String) priorityString); + } else { + priority = (Integer) priority; + } + + UserTask userTask = userTasks.userTaskById((String) workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID)); + + DefaultUserTaskInstance instance = (DefaultUserTaskInstance) userTask.createInstance(); + instance.setId(workItem.getStringId()); + instance.setTaskName((String) workItem.getParameter(TASK_NAME)); + instance.setTaskDescription((String) workItem.getParameter(DESCRIPTION)); + instance.setTaskPriority(priorityInteger); + instance.setExternalReferenceId(workItem.getStringId()); + instance.setMetadata("ProcessId", workItem.getProcessInstance().getProcessId()); + instance.setMetadata("ProcessType", workItem.getProcessInstance().getProcess().getType()); + instance.setMetadata("ProcessVersion", workItem.getProcessInstance().getProcessVersion()); + instance.setMetadata("ProcessInstanceId", workItem.getProcessInstance().getId()); + instance.setMetadata("ProcessInstanceState", workItem.getProcessInstance().getState()); + instance.setMetadata("RootProcessId", workItem.getProcessInstance().getRootProcessId()); + instance.setMetadata("RootProcessInstanceId", workItem.getProcessInstance().getRootProcessInstanceId()); + instance.setMetadata("ParentProcessInstanceId", workItem.getProcessInstance().getParentProcessInstanceId()); + + ofNullable(workItem.getParameters().get(ACTOR_ID)).map(String.class::cast).map(UserTaskKogitoWorkItemHandler::toSet).ifPresent(instance::setPotentialUsers); + ofNullable(workItem.getParameters().get(GROUP_ID)).map(String.class::cast).map(UserTaskKogitoWorkItemHandler::toSet).ifPresent(instance::setPotentialGroups); + ofNullable(workItem.getParameters().get(BUSINESSADMINISTRATOR_ID)).map(String.class::cast).map(UserTaskKogitoWorkItemHandler::toSet).ifPresent(instance::setAdminUsers); + ofNullable(workItem.getParameters().get(BUSINESSADMINISTRATOR_GROUP_ID)).map(String.class::cast).map(UserTaskKogitoWorkItemHandler::toSet).ifPresent(instance::setAdminGroups); + ofNullable(workItem.getParameters().get(EXCLUDED_OWNER_ID)).map(String.class::cast).map(UserTaskKogitoWorkItemHandler::toSet).ifPresent(instance::setExcludedUsers); + + instance.assign(); + instance.transition(instance.createTransitionToken("activate", emptyMap())); + + if (workItem instanceof InternalKogitoWorkItem ikw) { + ikw.setExternalReferenceId(instance.getId()); + ikw.setActualOwner(instance.getActualOwner()); + } + userTask.instances().create(instance); + return Optional.empty(); + } + + static protected Set toSet(String value) { + if (value == null) { + return null; + } + return Set.of(value.split(UT_SEPARATOR)); + } + + static public Optional userTaskClaimWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + workItem.removeOutput("ACTUAL_OWNER"); + + UserTasks userTasks = handler.getApplication().get(UserTasks.class); + UserTask userTask = userTasks.userTaskById((String) workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID)); + userTask.instances().findById(workItem.getExternalReferenceId()).ifPresent(ut -> { + Map data = transition.data(); + if (workItem instanceof InternalKogitoWorkItem ikw) { + getUserFromTransition(transition).ifPresent(ikw::setActualOwner); + if (data.containsKey("ACTUAL_OWNER") && ikw.getActualOwner() == null) { + ut.setActuaOwner((String) data.get("ACTUAL_OWNER")); + } + if (ikw.getActualOwner() == null) { + throw new InvalidTransitionException("transition claim does not contain user id"); + } + } + ut.setActuaOwner(workItem.getActualOwner()); + ut.transition(ut.createTransitionToken("claim", emptyMap())); + userTask.instances().update(ut); + }); + return Optional.empty(); + } + + static public Optional userTaskReleaseWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + if (workItem instanceof InternalKogitoWorkItem ikw) { + ikw.setActualOwner(null); + } + UserTasks userTasks = handler.getApplication().get(UserTasks.class); + UserTask userTask = userTasks.userTaskById((String) workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID)); + userTask.instances().findById(workItem.getExternalReferenceId()).ifPresent(ut -> { + ut.setActuaOwner(null); + ut.transition(ut.createTransitionToken("release", emptyMap())); + userTask.instances().update(ut); + }); + + return Optional.empty(); + } + + static public Optional userTaskCompleteWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + UserTasks userTasks = handler.getApplication().get(UserTasks.class); + UserTask userTask = userTasks.userTaskById((String) workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID)); + userTask.instances().findById(workItem.getExternalReferenceId()).ifPresent(ut -> { + ut.transition(ut.createTransitionToken("complete", emptyMap())); + userTask.instances().update(ut); + }); + if (workItem instanceof InternalKogitoWorkItem ikw && ikw.getActualOwner() == null) { + getUserFromTransition(transition).ifPresent(user -> { + ikw.setActualOwner(user); + }); + } + return Optional.empty(); + } + + static public Optional userTaskCompleteFromActiveWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, + WorkItemTransition transition) { + UserTasks userTasks = handler.getApplication().get(UserTasks.class); + UserTask userTask = userTasks.userTaskById((String) workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID)); + userTask.instances().findById(workItem.getExternalReferenceId()).ifPresent(ut -> { + ut.transition(ut.createTransitionToken("complete", emptyMap())); + userTask.instances().update(ut); + }); + if (workItem instanceof InternalKogitoWorkItem ikw) { + getUserFromTransition(transition).ifPresent(user -> { + ikw.setActualOwner(user); + }); + } + return Optional.empty(); + } + + static public Optional userTaskAbortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + UserTasks userTasks = handler.getApplication().get(UserTasks.class); + UserTask userTask = userTasks.userTaskById((String) workItem.getParameter(KogitoWorkItem.PARAMETER_UNIQUE_TASK_ID)); + userTask.instances().findById(workItem.getExternalReferenceId()).ifPresent(ut -> { + ut.transition(ut.createTransitionToken("skip", emptyMap())); + userTask.instances().update(ut); + }); + return Optional.empty(); + } + + private static Optional getUserFromTransition(WorkItemTransition transition) { + Optional securityPolicy = transition.policies().stream().filter(SecurityPolicy.class::isInstance).map(SecurityPolicy.class::cast).findAny(); + if (securityPolicy.isPresent()) { + return Optional.ofNullable(securityPolicy.get().getUser()); + } + return Optional.empty(); + } +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerFactory.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerFactory.java new file mode 100644 index 00000000000..4ffffbb56a5 --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/jbpm/usertask/handler/UserTaskKogitoWorkItemHandlerFactory.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.jbpm.usertask.handler; + +import java.util.List; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory; + +public class UserTaskKogitoWorkItemHandlerFactory implements KogitoWorkItemHandlerFactory { + + @Override + public List provide() { + return List.of(new UserTaskKogitoWorkItemHandler()); + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTask.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTask.java new file mode 100644 index 00000000000..92e2fa9c745 --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTask.java @@ -0,0 +1,303 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.kie.kogito.Application; +import org.kie.kogito.uow.events.UnitOfWorkUserTaskEventListener; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTaskConfig; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.UserTaskInstances; +import org.kie.kogito.usertask.impl.model.DeadlineHelper; +import org.kie.kogito.usertask.model.DeadlineInfo; +import org.kie.kogito.usertask.model.Reassignment; + +public class DefaultUserTask implements UserTask { + + private String separator = System.getProperty("org.jbpm.ht.user.separator", ","); + + private Application application; + private String id; + private UserTaskInstances userTaskInstances; + private String name; + private String taskName; + private String taskDescription; + private String referenceName; + private Integer taskPriority; + private Boolean skippable; + private Set potentialUsers; + private Set potentialGroups; + private Set adminUsers; + private Set adminGroups; + private Set excludedUsers; + private Collection>> startDeadlines; + private Collection>> endDeadlines; + private Collection> startReassigments; + private Collection> endReassigments; + + public DefaultUserTask() { + // nothing + } + + public DefaultUserTask(String id, String name) { + this(null, id, name, new InMemoryUserTaskInstances()); + } + + public DefaultUserTask(Application application, String id, String name) { + this(application, id, name, new InMemoryUserTaskInstances()); + } + + public DefaultUserTask(Application application, String id, String name, UserTaskInstances userTaskInstances) { + this.application = application; + this.id = id; + this.name = name; + this.userTaskInstances = userTaskInstances; + this.userTaskInstances.setReconnectUserTaskInstance(this::connect); + this.userTaskInstances.setDisconnectUserTaskInstance(this::disconnect); + this.skippable = Boolean.FALSE; + this.potentialUsers = new HashSet<>(); + this.potentialGroups = new HashSet<>(); + this.adminUsers = new HashSet<>(); + this.adminGroups = new HashSet<>(); + this.excludedUsers = new HashSet<>(); + this.startDeadlines = new HashSet<>(); + this.endDeadlines = new HashSet<>(); + this.startReassigments = new HashSet<>(); + this.endReassigments = new HashSet<>(); + + } + + public void setApplication(Application application) { + this.application = application; + } + + @Override + public UserTaskInstance createInstance() { + DefaultUserTaskInstance instance = new DefaultUserTaskInstance(this); + instance.setTaskName(getTaskName()); + instance.setTaskDescription(getTaskDescription()); + instance.setTaskPriority(getTaskPriority()); + instance.setPotentialUsers(getPotentialUsers()); + instance.setPotentialGroups(getPotentialGroups()); + instance.setAdminUsers(getAdminUsers()); + instance.setPotentialGroups(getPotentialGroups()); + instance.setExcludedUsers(getExcludedUsers()); + connect(instance); + return instance; + } + + private UserTaskInstance disconnect(UserTaskInstance userTaskInstance) { + DefaultUserTaskInstance instance = (DefaultUserTaskInstance) userTaskInstance; + instance.setUserTask(null); + instance.setUserTaskEventSupport(null); + instance.setUserTaskLifeCycle(null); + instance.setInstances(null); + return instance; + } + + public UserTaskInstance connect(UserTaskInstance userTaskInstance) { + DefaultUserTaskInstance instance = (DefaultUserTaskInstance) userTaskInstance; + UserTaskConfig userTaskConfig = application.config().get(UserTaskConfig.class); + KogitoUserTaskEventSupportImpl impl = new KogitoUserTaskEventSupportImpl(userTaskConfig.identityProvider()); + userTaskConfig.userTaskEventListeners().listeners().forEach(impl::addEventListener); + impl.addEventListener(new UnitOfWorkUserTaskEventListener(application.unitOfWorkManager())); + instance.setUserTask(this); + instance.setUserTaskEventSupport(impl); + instance.setUserTaskLifeCycle(userTaskConfig.userTaskLifeCycle()); + instance.setInstances(userTaskInstances); + return instance; + } + + @Override + public UserTaskInstances instances() { + return userTaskInstances; + } + + @Override + public String id() { + return id; + } + + @Override + public String name() { + return name; + } + + public void setSkippable(String skippable) { + this.skippable = Boolean.parseBoolean(skippable); + } + + public Boolean getSkippable() { + return skippable; + } + + @Override + public String getTaskName() { + return taskName; + } + + public void setTaskName(String taskName) { + this.taskName = taskName; + } + + @Override + public String getTaskDescription() { + return taskDescription; + } + + public void setTaskDescription(String taskDescription) { + this.taskDescription = taskDescription; + } + + @Override + public Integer getTaskPriority() { + return this.taskPriority; + } + + public void setTaskPriority(Integer taskPriority) { + this.taskPriority = taskPriority; + } + + public void setReferenceName(String referenceName) { + this.referenceName = referenceName; + } + + @Override + public String getReferenceName() { + return referenceName; + } + + @Override + public Set getPotentialUsers() { + return this.potentialUsers; + } + + public void setPotentialUsers(String potentialUsers) { + this.setPotentialUsers(toSet(potentialUsers)); + } + + public void setPotentialUsers(Set potentialUsers) { + this.potentialUsers = potentialUsers; + } + + @Override + public Set getPotentialGroups() { + return this.potentialGroups; + } + + public void setPotentialGroups(String potentialGroups) { + this.setPotentialGroups(toSet(potentialGroups)); + } + + public void setPotentialGroups(Set potentialGroups) { + this.potentialGroups = potentialGroups; + } + + @Override + public Set getAdminUsers() { + return this.adminUsers; + } + + public void setAdminUsers(String adminUsers) { + this.setAdminUsers(toSet(adminUsers)); + } + + public void setAdminUsers(Set adminUsers) { + this.adminUsers = adminUsers; + } + + @Override + public Set getAdminGroups() { + return this.adminGroups; + } + + public void setAdminGroups(String adminGroups) { + this.setAdminGroups(toSet(adminGroups)); + } + + public void setAdminGroups(Set adminGroups) { + this.adminGroups = adminGroups; + } + + @Override + public Set getExcludedUsers() { + return this.excludedUsers; + } + + public void setExcludedUsers(String excludedUsers) { + this.setExcludedUsers(toSet(excludedUsers)); + } + + public void setExcludedUsers(Set excludedUsers) { + this.excludedUsers = excludedUsers; + } + + @Override + public Collection>> getNotStartedDeadlines() { + return startDeadlines; + } + + public void setNotStartedDeadLines(String deadlines) { + this.startDeadlines = DeadlineHelper.parseDeadlines(deadlines); + } + + @Override + public Collection>> getNotCompletedDeadlines() { + return endDeadlines; + } + + public void setNotCompletedDeadlines(String notStarted) { + this.endDeadlines = DeadlineHelper.parseDeadlines(notStarted); + } + + @Override + public Collection> getNotStartedReassignments() { + return startReassigments; + } + + public void setNotStartedReassignments(String reassignments) { + this.startReassigments = DeadlineHelper.parseReassignments(reassignments); + } + + @Override + public Collection> getNotCompletedReassigments() { + return endReassigments; + } + + public void setNotCompletedReassigments(String reassignments) { + this.endReassigments = DeadlineHelper.parseReassignments(reassignments); + } + + protected Set toSet(String value) { + if (value == null) { + return new HashSet<>(); + } + Set store = new HashSet<>(); + for (String item : value.split(separator)) { + store.add(item); + } + return store; + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java new file mode 100644 index 00000000000..93d012f0116 --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskConfig.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Iterator; +import java.util.function.Supplier; + +import org.kie.kogito.auth.IdentityProvider; +import org.kie.kogito.jobs.JobsService; +import org.kie.kogito.services.identity.NoOpIdentityProvider; +import org.kie.kogito.services.uow.CollectingUnitOfWorkFactory; +import org.kie.kogito.services.uow.DefaultUnitOfWorkManager; +import org.kie.kogito.uow.UnitOfWorkManager; +import org.kie.kogito.usertask.UserTaskConfig; +import org.kie.kogito.usertask.UserTaskEventListenerConfig; +import org.kie.kogito.usertask.impl.lifecycle.DefaultUserTaskLifeCycle; +import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle; + +public class DefaultUserTaskConfig implements UserTaskConfig { + + private UserTaskEventListenerConfig userTaskEventListeners; + private UnitOfWorkManager unitOfWorkManager; + private JobsService jobService; + private IdentityProvider identityProvider; + private UserTaskLifeCycle userTaskLifeCycle; + + public DefaultUserTaskConfig() { + this(new DefaultUserTaskEventListenerConfig(), + new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()), + null, + new NoOpIdentityProvider(), + new DefaultUserTaskLifeCycle()); + } + + public DefaultUserTaskConfig( + Iterable userTaskEventListenerConfig, + Iterable unitOfWorkManager, + Iterable jobService, + Iterable identityProvider, + Iterable userTaskLifeCycle) { + + this.userTaskEventListeners = singleton(userTaskEventListenerConfig, DefaultUserTaskEventListenerConfig::new); + this.unitOfWorkManager = singleton(unitOfWorkManager, () -> new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())); + this.jobService = singleton(jobService, () -> null); + this.identityProvider = singleton(identityProvider, NoOpIdentityProvider::new); + this.userTaskLifeCycle = singleton(userTaskLifeCycle, DefaultUserTaskLifeCycle::new); + + } + + private T singleton(Iterable value, Supplier defaultValue) { + Iterator iterator = value.iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } + return defaultValue.get(); + } + + public DefaultUserTaskConfig( + UserTaskEventListenerConfig userTaskEventListenerConfig, + UnitOfWorkManager unitOfWorkManager, + JobsService jobService, + IdentityProvider identityProvider, + UserTaskLifeCycle userTaskLifeCycle) { + this.userTaskEventListeners = userTaskEventListenerConfig; + this.unitOfWorkManager = unitOfWorkManager; + this.jobService = jobService; + this.identityProvider = identityProvider; + this.userTaskLifeCycle = userTaskLifeCycle; + } + + @Override + public UserTaskEventListenerConfig userTaskEventListeners() { + return userTaskEventListeners; + } + + @Override + public UnitOfWorkManager unitOfWorkManager() { + return unitOfWorkManager; + } + + @Override + public JobsService jobsService() { + return jobService; + } + + @Override + public IdentityProvider identityProvider() { + return identityProvider; + } + + @Override + public UserTaskLifeCycle userTaskLifeCycle() { + return userTaskLifeCycle; + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskEventListenerConfig.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskEventListenerConfig.java new file mode 100644 index 00000000000..9cb7f3ac09e --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskEventListenerConfig.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.kie.kogito.usertask.UserTaskEventListener; +import org.kie.kogito.usertask.UserTaskEventListenerConfig; + +public class DefaultUserTaskEventListenerConfig implements UserTaskEventListenerConfig { + + private List listeners; + + public DefaultUserTaskEventListenerConfig() { + this.listeners = new ArrayList<>(); + } + + public DefaultUserTaskEventListenerConfig(List listeners) { + this.listeners = new ArrayList<>(listeners); + } + + public void addUserTaskEventListener(UserTaskEventListener userTaskEventListener) { + this.listeners.add(userTaskEventListener); + } + + @Override + public List listeners() { + return listeners; + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java new file mode 100644 index 00000000000..8adb9f07d02 --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTaskInstance.java @@ -0,0 +1,481 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +import org.kie.kogito.internal.usertask.event.KogitoUserTaskEventSupport; +import org.kie.kogito.internal.usertask.event.KogitoUserTaskEventSupport.AssignmentType; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.UserTaskInstances; +import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle; +import org.kie.kogito.usertask.lifecycle.UserTaskState; +import org.kie.kogito.usertask.lifecycle.UserTaskTransition; +import org.kie.kogito.usertask.lifecycle.UserTaskTransitionToken; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.Comment; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class DefaultUserTaskInstance implements UserTaskInstance { + + private String id; + + private UserTaskState status; + private String actualOwner; + private String taskName; + private String taskDescription; + private Integer taskPriority; + private Set potentialUsers; + private Set potentialGroups; + private Set adminUsers; + private Set adminGroups; + private Set excludedUsers; + private List attachments; + private List comments; + private String externalReferenceId; + + private Map inputs; + private Map outputs; + + private Map metadata; + @JsonIgnore + private UserTaskInstances instances; + + @JsonIgnore + private UserTask userTask; + @JsonIgnore + private KogitoUserTaskEventSupport userTaskEventSupport; + @JsonIgnore + private UserTaskLifeCycle setUserTaskLifeCycle; + + public DefaultUserTaskInstance() { + this.metadata = new HashMap<>(); + this.attachments = new ArrayList<>(); + this.comments = new ArrayList<>(); + this.potentialUsers = new HashSet<>(); + this.potentialGroups = new HashSet<>(); + this.adminUsers = new HashSet<>(); + this.adminGroups = new HashSet<>(); + this.excludedUsers = new HashSet<>(); + } + + public DefaultUserTaskInstance(UserTask userTask) { + this.id = UUID.randomUUID().toString(); + this.userTask = userTask; + this.instances = userTask.instances(); + this.status = UserTaskState.initalized(); + this.metadata = new HashMap<>(); + this.attachments = new ArrayList<>(); + this.comments = new ArrayList<>(); + this.potentialUsers = new HashSet<>(); + this.potentialGroups = new HashSet<>(); + this.adminUsers = new HashSet<>(); + this.adminGroups = new HashSet<>(); + this.excludedUsers = new HashSet<>(); + } + + public void assign() { + Set potentialUsers = new HashSet<>(this.getPotentialUsers()); + potentialUsers.removeAll(getExcludedUsers()); + + if (potentialUsers.size() == 1) { + this.actualOwner = potentialUsers.iterator().next(); + } + } + + public void setUserTaskEventSupport(KogitoUserTaskEventSupport userTaskEventSupport) { + this.userTaskEventSupport = userTaskEventSupport; + } + + public void setUserTaskLifeCycle(UserTaskLifeCycle userTaskLifeCycle) { + this.setUserTaskLifeCycle = userTaskLifeCycle; + } + + public void setInstances(UserTaskInstances instances) { + this.instances = instances; + } + + @Override + public void complete() { + UserTaskTransitionToken transition = this.setUserTaskLifeCycle.newCompleteTransitionToken(this, Collections.emptyMap()); + transition(transition); + instances.remove(id); + } + + @Override + public void abort() { + UserTaskTransitionToken transition = this.setUserTaskLifeCycle.newAbortTransitionToken(this, Collections.emptyMap()); + transition(transition); + instances.remove(id); + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String getId() { + return this.id; + } + + public void setStatus(UserTaskState status) { + this.status = status; + } + + @Override + public UserTaskState getStatus() { + return status; + } + + @Override + public boolean hasActualOwner() { + return actualOwner != null; + } + + @Override + public void setActuaOwner(String actualOwner) { + this.actualOwner = actualOwner; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOneUserTaskStateChange(this, this.status.getName(), this.status.getName()); + } + } + + @Override + public String getActualOwner() { + return actualOwner; + } + + @Override + public String getExternalReferenceId() { + return externalReferenceId; + } + + public void setExternalReferenceId(String externalReferenceId) { + this.externalReferenceId = externalReferenceId; + } + + @Override + public UserTaskTransitionToken createTransitionToken(String transitionId, Map data) { + return this.setUserTaskLifeCycle.newTransitionToken(transitionId, this, data); + } + + @Override + public void transition(UserTaskTransitionToken token) { + Optional next = Optional.of(token); + while (next.isPresent()) { + UserTaskTransition transition = next.get().transition(); + next = this.setUserTaskLifeCycle.transition(this, token); + this.status = transition.target(); + this.userTaskEventSupport.fireOneUserTaskStateChange(this, transition.source().getName(), transition.target().getName()); + if (this.status.isTerminate().isPresent()) { + this.instances.remove(this.id); + } + } + } + + @Override + public UserTask getUserTask() { + return userTask; + } + + public void setUserTask(DefaultUserTask userTask) { + this.userTask = userTask; + } + + public Map getInputs() { + return inputs; + } + + public void setInputs(Map inputs) { + this.inputs = inputs; + } + + public Map getOutputs() { + return outputs; + } + + public void setOutputs(Map outputs) { + this.outputs = outputs; + } + + /** + * Returns name of the task + * + * @return task name + */ + @Override + public String getTaskName() { + return taskName; + } + + public void setTaskName(String taskName) { + this.taskName = taskName; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOneUserTaskStateChange(this, this.status.getName(), this.status.getName()); + } + } + + /** + * Returns optional description of the task + * + * @return task description if present + */ + @Override + public String getTaskDescription() { + return this.taskDescription; + } + + public void setTaskDescription(String taskDescription) { + this.taskDescription = taskDescription; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOneUserTaskStateChange(this, this.status.getName(), this.status.getName()); + } + } + + /** + * Returns optional priority of the task + * + * @return task priority if present + */ + @Override + public Integer getTaskPriority() { + return this.taskPriority; + } + + public void setTaskPriority(Integer taskPriority) { + this.taskPriority = taskPriority; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOneUserTaskStateChange(this, this.status.getName(), this.status.getName()); + } + } + + /** + * Returns potential users that can work on this task + * + * @return potential users + */ + @Override + public Set getPotentialUsers() { + return this.potentialUsers; + } + + public void setPotentialUsers(Set potentialUsers) { + Set oldValues = new HashSet<>(this.potentialUsers); + this.potentialUsers = potentialUsers; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAssignmentChange(this, AssignmentType.USER_OWNERS, oldValues, potentialUsers); + } + } + + /** + * Returns potential groups that can work on this task + * + * @return potential groups + */ + @Override + public Set getPotentialGroups() { + return this.potentialGroups; + } + + public void setPotentialGroups(Set potentialGroups) { + Set oldValues = new HashSet<>(this.potentialGroups); + this.potentialGroups = potentialGroups; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAssignmentChange(this, AssignmentType.USER_GROUPS, oldValues, potentialGroups); + } + } + + /** + * Returns admin users that can administer this task + * + * @return admin users + */ + @Override + public Set getAdminUsers() { + return this.adminUsers; + } + + public void setAdminUsers(Set adminUsers) { + Set oldValues = new HashSet<>(this.adminUsers); + this.adminUsers = adminUsers; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAssignmentChange(this, AssignmentType.ADMIN_USERS, oldValues, adminUsers); + } + } + + /** + * Returns admin groups that can administer this task + * + * @return admin groups + */ + @Override + public Set getAdminGroups() { + return this.adminGroups; + } + + public void setAdminGroups(Set adminGroups) { + Set oldValues = new HashSet<>(this.adminGroups); + this.adminGroups = adminGroups; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAssignmentChange(this, AssignmentType.ADMIN_GROUPS, oldValues, adminGroups); + } + } + + /** + * Returns excluded users that cannot work on this task + * + * @return excluded users + */ + @Override + public Set getExcludedUsers() { + return this.excludedUsers; + } + + public void setExcludedUsers(Set excludedUsers) { + Set oldValues = new HashSet<>(this.excludedUsers); + this.excludedUsers = excludedUsers; + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAssignmentChange(this, AssignmentType.USERS_EXCLUDED, oldValues, excludedUsers); + } + } + + /** + * Returns task attachments + * + * @return A map which key is the attachment id and value the attachment object + */ + public List getAttachments() { + return attachments; + } + + @Override + public void addAttachment(Attachment attachment) { + this.attachments.add(attachment); + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAttachmentAdded(this, attachment); + } + } + + @Override + public void updateAttachment(Attachment newAttachment) { + Optional oldAttachment = this.attachments.stream().filter(e -> e.getId().equals(newAttachment.getId())).findFirst(); + if (oldAttachment.isEmpty()) { + return; + } + this.attachments.remove(oldAttachment.get()); + this.attachments.add(newAttachment); + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAttachmentChange(this, oldAttachment.get(), newAttachment); + } + } + + @Override + public void removeAttachment(Attachment oldAttachment) { + this.attachments.remove(oldAttachment); + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskAttachmentDeleted(this, oldAttachment); + } + } + + public void setAttachments(List attachments) { + this.attachments = attachments; + + } + + /** + * Returns task comments + * + * @return A map which key is the comment id and value the comment object + */ + public List getComments() { + return comments; + } + + @Override + public void addComment(Comment comment) { + this.comments.add(comment); + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskCommentAdded(this, comment); + } + } + + @Override + public void updateComment(Comment newComment) { + Optional oldComment = this.comments.stream().filter(e -> e.getId().equals(newComment.getId())).findFirst(); + if (oldComment.isEmpty()) { + return; + } + this.comments.remove(oldComment.get()); + this.comments.add(newComment); + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskCommentChange(this, oldComment.get(), newComment); + } + } + + @Override + public void removeComment(Comment comment) { + this.comments.remove(comment); + if (this.userTaskEventSupport != null) { + this.userTaskEventSupport.fireOnUserTaskCommentDeleted(this, comment); + } + } + + public void setComments(List comments) { + this.comments = comments; + } + + public void setMetadata(String key, Object value) { + this.metadata.put(key, value); + } + + public Map getMetadata() { + return metadata; + } + + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + @Override + public Attachment findAttachmentById(String attachmentId) { + return this.attachments.stream().filter(e -> e.getId().equals(attachmentId)).findAny().orElse(null); + } + + @Override + public Comment findCommentById(String commentId) { + return this.comments.stream().filter(e -> e.getId().equals(commentId)).findAny().orElse(null); + } + + @Override + public String toString() { + return "DefaultUserTaskInstance [id=" + id + ", status=" + status + ", actualOwner=" + actualOwner + ", taskName=" + taskName + ", taskDescription=" + taskDescription + ", taskPriority=" + + taskPriority + "]"; + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java new file mode 100644 index 00000000000..a2a664e82d8 --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/DefaultUserTasks.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.kie.kogito.Application; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTasks; + +public class DefaultUserTasks implements UserTasks { + + private Map userTasks; + private Application application; + + public DefaultUserTasks() { + this.userTasks = new HashMap<>(); + } + + public DefaultUserTasks(Application application, UserTask... userTasks) { + this(application, List.of(userTasks)); + } + + public DefaultUserTasks(Application application, Iterable userTasks) { + this.application = application; + this.userTasks = new HashMap<>(); + Iterator userTaskIterator = userTasks.iterator(); + while (userTaskIterator.hasNext()) { + UserTask userTask = userTaskIterator.next(); + this.userTasks.put(userTask.id(), userTask); + } + } + + @Override + public UserTask userTaskById(String userTaskId) { + return userTasks.get(userTaskId); + } + + @Override + public Collection userTaskIds() { + return userTasks.keySet(); + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java new file mode 100644 index 00000000000..6704fbd83a8 --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/InMemoryUserTaskInstances.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.UserTaskInstances; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class InMemoryUserTaskInstances implements UserTaskInstances { + + private Map userTaskInstances; + private Function reconnectUserTaskInstance; + private Function disconnectUserTaskInstance; + private ObjectMapper mapper; + + public InMemoryUserTaskInstances() { + this.userTaskInstances = new HashMap<>(); + this.reconnectUserTaskInstance = Function.identity(); + this.disconnectUserTaskInstance = Function.identity(); + this.mapper = new ObjectMapper(); + } + + @Override + public void setReconnectUserTaskInstance(Function reconnectUserTaskInstance) { + this.reconnectUserTaskInstance = reconnectUserTaskInstance; + } + + @Override + public void setDisconnectUserTaskInstance(Function disconnectUserTaskInstance) { + this.disconnectUserTaskInstance = disconnectUserTaskInstance; + } + + @Override + public Optional findById(String userTaskInstanceId) { + try { + UserTaskInstance userTaskInstance = mapper.readValue(userTaskInstances.get(userTaskInstanceId), DefaultUserTaskInstance.class); + return Optional.ofNullable(reconnectUserTaskInstance.apply(userTaskInstance)); + } catch (Exception e) { + return Optional.empty(); + } + } + + @Override + public boolean exists(String userTaskInstanceId) { + return userTaskInstances.containsKey(userTaskInstanceId); + } + + @Override + public UserTaskInstance create(UserTaskInstance userTaskInstance) { + try { + byte[] data = mapper.writeValueAsBytes(userTaskInstance); + userTaskInstances.put(userTaskInstance.getId(), data); + return reconnectUserTaskInstance.apply(userTaskInstance); + } catch (Exception e) { + return null; + } + } + + @Override + public UserTaskInstance update(UserTaskInstance userTaskInstance) { + try { + byte[] data = mapper.writeValueAsBytes(userTaskInstance); + userTaskInstances.put(userTaskInstance.getId(), data); + return userTaskInstance; + } catch (Exception e) { + return null; + } + } + + @Override + public UserTaskInstance remove(String userTaskInstanceId) { + try { + return disconnectUserTaskInstance.apply(mapper.readValue(userTaskInstances.remove(userTaskInstanceId), DefaultUserTaskInstance.class)); + } catch (Exception e) { + return null; + } + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/KogitoUserTaskEventSupportImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/KogitoUserTaskEventSupportImpl.java new file mode 100644 index 00000000000..1a2c3be5d6e --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/KogitoUserTaskEventSupportImpl.java @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; + +import org.kie.kogito.auth.IdentityProvider; +import org.kie.kogito.internal.usertask.event.KogitoUserTaskEventSupport; +import org.kie.kogito.usertask.UserTaskEventListener; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskDeadlineEvent; +import org.kie.kogito.usertask.events.UserTaskDeadlineEvent.DeadlineType; +import org.kie.kogito.usertask.events.UserTaskVariableEvent.VariableEventType; +import org.kie.kogito.usertask.impl.events.UserTaskAssignmentEventImpl; +import org.kie.kogito.usertask.impl.events.UserTaskAttachmentEventImpl; +import org.kie.kogito.usertask.impl.events.UserTaskCommentEventImpl; +import org.kie.kogito.usertask.impl.events.UserTaskDeadlineEventImpl; +import org.kie.kogito.usertask.impl.events.UserTaskStateEventImpl; +import org.kie.kogito.usertask.impl.events.UserTaskVariableEventImpl; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.Comment; + +public class KogitoUserTaskEventSupportImpl implements KogitoUserTaskEventSupport { + + private List listeners; + + private IdentityProvider identityProvider; + + /** + * Do not use this constructor. It should be used just by deserialization. + */ + public KogitoUserTaskEventSupportImpl(IdentityProvider identityProvider) { + this.identityProvider = identityProvider; + this.listeners = new CopyOnWriteArrayList<>(); + } + + private void notifyAllListeners(Consumer consumer) { + this.listeners.forEach(consumer::accept); + } + + // users tasks events + @Override + public void fireOnUserTaskNotStartedDeadline( + UserTaskInstance userTaskInstance, + Map notification) { + fireUserTaskNotification(userTaskInstance, notification, DeadlineType.Started); + } + + @Override + public void fireOnUserTaskNotCompletedDeadline( + UserTaskInstance userTaskInstance, + Map notification) { + fireUserTaskNotification(userTaskInstance, notification, DeadlineType.Completed); + } + + private void fireUserTaskNotification( + UserTaskInstance userTaskInstance, + Map notification, + DeadlineType type) { + UserTaskDeadlineEvent event = new UserTaskDeadlineEventImpl(userTaskInstance, notification, type, identityProvider.getName()); + notifyAllListeners(l -> l.onUserTaskDeadline(event)); + } + + @Override + public void fireOneUserTaskStateChange( + UserTaskInstance userTaskInstance, + String oldStatus, String newStatus) { + UserTaskStateEventImpl event = new UserTaskStateEventImpl(userTaskInstance, oldStatus, newStatus, identityProvider.getName()); + event.setOldStatus(oldStatus); + event.setNewStatus(newStatus); + notifyAllListeners(l -> l.onUserTaskState(event)); + } + + @Override + public void fireOnUserTaskAssignmentChange( + UserTaskInstance userTaskInstance, + AssignmentType assignmentType, + Set oldUsersId, Set newUsersId) { + UserTaskAssignmentEventImpl event = new UserTaskAssignmentEventImpl(userTaskInstance, assignmentType.name(), oldUsersId, newUsersId, identityProvider.getName()); + event.setAssignmentType(assignmentType.name()); + notifyAllListeners(l -> l.onUserTaskAssignment(event)); + } + + @Override + public void fireOnUserTaskInputVariableChange( + UserTaskInstance userTaskInstance, + String variableName, Object newValue, Object oldValue) { + UserTaskVariableEventImpl event = new UserTaskVariableEventImpl(userTaskInstance, variableName, oldValue, newValue, VariableEventType.INPUT, identityProvider.getName()); + notifyAllListeners(l -> l.onUserTaskInputVariable(event)); + } + + @Override + public void fireOnUserTaskOutputVariableChange( + UserTaskInstance userTaskInstance, + String variableName, Object newValue, Object oldValue) { + UserTaskVariableEventImpl event = new UserTaskVariableEventImpl(userTaskInstance, variableName, oldValue, newValue, VariableEventType.OUTPUT, identityProvider.getName()); + notifyAllListeners(l -> l.onUserTaskOutputVariable(event)); + } + + @Override + public void fireOnUserTaskAttachmentAdded( + UserTaskInstance userTaskInstance, + Attachment addedAttachment) { + + UserTaskAttachmentEventImpl event = new UserTaskAttachmentEventImpl(userTaskInstance, identityProvider.getName()); + event.setNewAttachment(addedAttachment); + notifyAllListeners(l -> l.onUserTaskAttachmentAdded(event)); + } + + @Override + public void fireOnUserTaskAttachmentChange( + UserTaskInstance userTaskInstance, + Attachment oldAttachment, Attachment newAttachment) { + UserTaskAttachmentEventImpl event = new UserTaskAttachmentEventImpl(userTaskInstance, identityProvider.getName()); + event.setOldAttachment(oldAttachment); + event.setNewAttachment(newAttachment); + notifyAllListeners(l -> l.onUserTaskAttachmentChange(event)); + } + + @Override + public void fireOnUserTaskAttachmentDeleted( + UserTaskInstance userTaskInstance, + Attachment deletedAttachment) { + UserTaskAttachmentEventImpl event = new UserTaskAttachmentEventImpl(userTaskInstance, identityProvider.getName()); + event.setOldAttachment(deletedAttachment); + notifyAllListeners(l -> l.onUserTaskAttachmentDeleted(event)); + } + + @Override + public void fireOnUserTaskCommentAdded( + UserTaskInstance userTaskInstance, + Comment addedComment) { + UserTaskCommentEventImpl event = new UserTaskCommentEventImpl(userTaskInstance, identityProvider.getName()); + event.setNewComment(addedComment); + notifyAllListeners(l -> l.onUserTaskCommentAdded(event)); + } + + @Override + public void fireOnUserTaskCommentChange( + UserTaskInstance userTaskInstance, + Comment oldComment, Comment newComment) { + UserTaskCommentEventImpl event = new UserTaskCommentEventImpl(userTaskInstance, identityProvider.getName()); + event.setOldComment(oldComment); + event.setNewComment(newComment); + notifyAllListeners(l -> l.onUserTaskCommentChange(event)); + } + + @Override + public void fireOnUserTaskCommentDeleted( + UserTaskInstance userTaskInstance, + Comment deletedComment) { + UserTaskCommentEventImpl event = new UserTaskCommentEventImpl(userTaskInstance, identityProvider.getName()); + event.setOldComment(deletedComment); + notifyAllListeners(l -> l.onUserTaskCommentDeleted(event)); + } + + @Override + public void reset() { + this.listeners.clear(); + } + + @Override + public void addEventListener(UserTaskEventListener listener) { + if (!this.listeners.contains(listener)) { + this.listeners.add(listener); + } + } + + @Override + public void removeEventListener(UserTaskEventListener listener) { + this.listeners.remove(listener); + } + +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAssignmentEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAssignmentEventImpl.java similarity index 58% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAssignmentEventImpl.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAssignmentEventImpl.java index f2fb0a7a33c..aafd2daa1cd 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskAssignmentEventImpl.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAssignmentEventImpl.java @@ -16,29 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.event; +package org.kie.kogito.usertask.impl.events; +import java.util.HashSet; import java.util.Set; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskAssignmentEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskAssignmentEvent; public class UserTaskAssignmentEventImpl extends UserTaskEventImpl implements UserTaskAssignmentEvent { - private static final long serialVersionUID = 1964525156416025043L; + private static final long serialVersionUID = 3388030428744037024L; private String assignmentType; - private String[] oldUsersId; - private String[] newUsersId; + private Set oldUsersId; + private Set newUsersId; - public UserTaskAssignmentEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime, String identity) { - super(instance, nodeInstance, kruntime, identity); - } - - @Override - public String getUserTaskId() { - return getHumanTaskNodeInstance().getWorkItemId(); + public UserTaskAssignmentEventImpl(UserTaskInstance userTaskInstance, String assignmentType, Set oldUserId, Set newUserId, String user) { + super(userTaskInstance, user); + this.assignmentType = assignmentType; + this.oldUsersId = oldUserId; + this.newUsersId = newUserId; } public void setAssignmentType(String name) { @@ -47,12 +44,12 @@ public void setAssignmentType(String name) { } public void setOldUsersId(Set oldUsersId) { - this.oldUsersId = oldUsersId.toArray(String[]::new); + this.oldUsersId = new HashSet<>(oldUsersId); } public void setNewUsersId(Set newUsersId) { - this.newUsersId = newUsersId.toArray(String[]::new); + this.newUsersId = new HashSet<>(newUsersId); } @Override @@ -62,11 +59,16 @@ public String getAssignmentType() { @Override public String[] getOldUsersId() { - return oldUsersId; + return oldUsersId.toArray(String[]::new); } @Override public String[] getNewUsersId() { - return newUsersId; + return newUsersId.toArray(String[]::new); + } + + @Override + public String toString() { + return "UserTaskAssignmentEventImpl [assignmentType=" + assignmentType + ", oldUsersId=" + oldUsersId + ", newUsersId=" + newUsersId + "]"; } } diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAttachmentEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAttachmentEventImpl.java new file mode 100644 index 00000000000..68df2a5b2fe --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskAttachmentEventImpl.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.impl.events; + +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskAttachmentEvent; +import org.kie.kogito.usertask.model.Attachment; + +public class UserTaskAttachmentEventImpl extends UserTaskEventImpl implements UserTaskAttachmentEvent { + + private static final long serialVersionUID = 3956348350804141924L; + private Attachment oldAttachment; + private Attachment newAttachment; + + public UserTaskAttachmentEventImpl(UserTaskInstance userTaskInstance, String user) { + super(userTaskInstance, user); + } + + public void setOldAttachment(Attachment oldAttachment) { + this.oldAttachment = oldAttachment; + } + + public void setNewAttachment(Attachment newAttachment) { + this.newAttachment = newAttachment; + } + + @Override + public Attachment getOldAttachment() { + return oldAttachment; + } + + @Override + public Attachment getNewAttachment() { + return newAttachment; + } + + @Override + public String toString() { + return "UserTaskAttachmentEventImpl [oldAttachment=" + oldAttachment + ", newAttachment=" + newAttachment + "]"; + } + +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskCommentEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskCommentEventImpl.java new file mode 100644 index 00000000000..6a1c163364d --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskCommentEventImpl.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.impl.events; + +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskCommentEvent; +import org.kie.kogito.usertask.model.Comment; + +public class UserTaskCommentEventImpl extends UserTaskEventImpl implements UserTaskCommentEvent { + + private static final long serialVersionUID = -7962827076724999755L; + private Comment oldComment; + private Comment newComment; + + public UserTaskCommentEventImpl(UserTaskInstance usertaskInstance, String user) { + super(usertaskInstance, user); + } + + public void setOldComment(Comment oldComment) { + this.oldComment = oldComment; + } + + public void setNewComment(Comment newComment) { + this.newComment = newComment; + } + + @Override + public Comment getNewComment() { + return newComment; + } + + @Override + public Comment getOldComment() { + return oldComment; + } + + @Override + public String toString() { + return "UserTaskCommentEventImpl [oldComment=" + oldComment + ", newComment=" + newComment + "]"; + } + +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskDeadlineEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskDeadlineEventImpl.java similarity index 62% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskDeadlineEventImpl.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskDeadlineEventImpl.java index c660f92498a..720054cf063 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskDeadlineEventImpl.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskDeadlineEventImpl.java @@ -16,27 +16,22 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.event; +package org.kie.kogito.usertask.impl.events; import java.util.Map; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskDeadlineEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskDeadlineEvent; public class UserTaskDeadlineEventImpl extends UserTaskEventImpl implements UserTaskDeadlineEvent { + private static final long serialVersionUID = 510l; - private HumanTaskWorkItem workItem; private Map notification; private DeadlineType type; - public UserTaskDeadlineEventImpl(ProcessInstance instance, HumanTaskNodeInstance humanTaskNodeInstance, HumanTaskWorkItem workItem, - Map notification, DeadlineType type, KieRuntime kruntime, String identity) { - super(instance, humanTaskNodeInstance, kruntime, identity); - this.workItem = workItem; + public UserTaskDeadlineEventImpl(UserTaskInstance userTaskInstance, Map notification, DeadlineType type, String user) { + super(userTaskInstance, user); this.notification = notification; this.type = type; } @@ -53,7 +48,7 @@ public DeadlineType getType() { @Override public String toString() { - return "HumanTaskDeadlineEventImpl [workItem=" + workItem + ", notification=" + notification + ", type=" + - type + "]"; + return "HumanTaskDeadlineEventImpl [notification=" + notification + ", type=" + type + "]"; } + } diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskEventImpl.java new file mode 100644 index 00000000000..c0fc530e0db --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskEventImpl.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.usertask.impl.events; + +import java.util.Date; +import java.util.EventObject; + +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskEvent; + +public class UserTaskEventImpl extends EventObject implements UserTaskEvent { + + private static final long serialVersionUID = 5290126847252514783L; + + public UserTaskEventImpl(UserTaskInstance userTaskInstance, String user) { + super(userTaskInstance); + this.userTaskInstance = userTaskInstance; + this.eventDate = new Date(); + this.eventUser = user; + } + + private UserTaskInstance userTaskInstance; + private final Date eventDate; + private final String eventUser; + + @Override + public UserTask getUserTask() { + return userTaskInstance.getUserTask(); + } + + @Override + public UserTaskInstance getSource() { + return (UserTaskInstance) super.getSource(); + } + + @Override + public UserTaskInstance getUserTaskInstance() { + return userTaskInstance; + } + + @Override + public Date getEventDate() { + return eventDate; + } + + @Override + public String getEventUser() { + return eventUser; + } + + @Override + public String toString() { + return "UserTaskEventImpl [userTaskInstance=" + userTaskInstance + ", eventDate=" + eventDate + ", eventUser=" + eventUser + "]"; + } + +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskStateEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskStateEventImpl.java similarity index 71% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskStateEventImpl.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskStateEventImpl.java index 2cacd6063fa..1bc9005e1f3 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskStateEventImpl.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskStateEventImpl.java @@ -16,12 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.event; +package org.kie.kogito.usertask.impl.events; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskStateEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskStateEvent; public class UserTaskStateEventImpl extends UserTaskEventImpl implements UserTaskStateEvent { @@ -29,13 +27,8 @@ public class UserTaskStateEventImpl extends UserTaskEventImpl implements UserTas private String oldStatus; private String newStatus; - public UserTaskStateEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime, String identity) { - super(instance, nodeInstance, kruntime, identity); - } - - @Override - public String getUserTaskDefinitionId() { - return getHumanTaskNodeInstance().getNodeDefinitionId(); + public UserTaskStateEventImpl(UserTaskInstance userTaskInstance, String oldStatus, String newStatus, String user) { + super(userTaskInstance, user); } public void setOldStatus(String oldStatus) { @@ -57,4 +50,10 @@ public String getNewStatus() { public String getOldStatus() { return oldStatus; } + + @Override + public String toString() { + return "UserTaskStateEventImpl [oldStatus=" + oldStatus + ", newStatus=" + newStatus + "]"; + } + } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskVariableEventImpl.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskVariableEventImpl.java similarity index 80% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskVariableEventImpl.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskVariableEventImpl.java index c833b187dd1..06dc327b171 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/UserTaskVariableEventImpl.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/events/UserTaskVariableEventImpl.java @@ -17,12 +17,10 @@ * under the License. */ -package org.jbpm.process.instance.event; +package org.kie.kogito.usertask.impl.events; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.kie.api.event.usertask.UserTaskVariableEvent; -import org.kie.api.runtime.KieRuntime; -import org.kie.api.runtime.process.ProcessInstance; +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.events.UserTaskVariableEvent; public class UserTaskVariableEventImpl extends UserTaskEventImpl implements UserTaskVariableEvent { @@ -32,8 +30,12 @@ public class UserTaskVariableEventImpl extends UserTaskEventImpl implements User private Object newValue; private VariableEventType variableType; - public UserTaskVariableEventImpl(ProcessInstance instance, HumanTaskNodeInstance nodeInstance, KieRuntime kruntime, String identity) { - super(instance, nodeInstance, kruntime, identity); + public UserTaskVariableEventImpl(UserTaskInstance usertaskInstance, String varName, Object oldValue, Object newValue, VariableEventType variableType, String user) { + super(usertaskInstance, user); + this.variableName = varName; + this.oldValue = oldValue; + this.newValue = newValue; + this.variableType = variableType; } public void setVariableName(String variableName) { diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java new file mode 100644 index 00000000000..da681ed8f4d --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskLifeCycle.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl.lifecycle; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.kie.kogito.usertask.UserTaskInstance; +import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle; +import org.kie.kogito.usertask.lifecycle.UserTaskState; +import org.kie.kogito.usertask.lifecycle.UserTaskState.TerminationType; +import org.kie.kogito.usertask.lifecycle.UserTaskTransition; +import org.kie.kogito.usertask.lifecycle.UserTaskTransitionToken; + +public class DefaultUserTaskLifeCycle implements UserTaskLifeCycle { + + public static final UserTaskState INACTIVE = UserTaskState.of(null); + public static final UserTaskState ACTIVE = UserTaskState.of("Ready"); + public static final UserTaskState RESERVED = UserTaskState.of("Reserved"); + public static final UserTaskState COMPLETED = UserTaskState.of("Completed", TerminationType.COMPLETED); + public static final UserTaskState ERROR = UserTaskState.of("Error", TerminationType.ERROR); + public static final UserTaskState OBSOLETE = UserTaskState.of("Obsolete", TerminationType.OBSOLETE); + + private static final UserTaskTransition T_NEW_ACTIVE = new DefaultUserTransition("activate", INACTIVE, ACTIVE, DefaultUserTaskLifeCycle::activate); + private static final UserTaskTransition T_ACTIVE_RESERVED = new DefaultUserTransition("claim", ACTIVE, RESERVED, DefaultUserTaskLifeCycle::claim); + private static final UserTaskTransition T_RESERVED_ACTIVE = new DefaultUserTransition("release", RESERVED, ACTIVE, DefaultUserTaskLifeCycle::release); + private static final UserTaskTransition T_ACTIVE_COMPLETED = new DefaultUserTransition("complete", ACTIVE, COMPLETED, DefaultUserTaskLifeCycle::complete); + private static final UserTaskTransition T_RESERVED_COMPLETED = new DefaultUserTransition("complete", RESERVED, COMPLETED, DefaultUserTaskLifeCycle::complete); + private static final UserTaskTransition T_RESERVED_SKIPPED = new DefaultUserTransition("skip", RESERVED, OBSOLETE, DefaultUserTaskLifeCycle::skip); + private static final UserTaskTransition T_ACTIVE_SKIPPED = new DefaultUserTransition("skip", ACTIVE, OBSOLETE, DefaultUserTaskLifeCycle::complete); + private static final UserTaskTransition T_RESERVED_ERROR = new DefaultUserTransition("fail", RESERVED, ERROR, DefaultUserTaskLifeCycle::fail); + + private List transitions; + + public DefaultUserTaskLifeCycle() { + transitions = List.of( + T_NEW_ACTIVE, + T_ACTIVE_RESERVED, + T_RESERVED_ACTIVE, + T_ACTIVE_COMPLETED, + T_RESERVED_COMPLETED, + T_ACTIVE_SKIPPED, + T_RESERVED_SKIPPED, + T_RESERVED_ERROR); + } + + @Override + public Optional transition(UserTaskInstance userTaskInstance, UserTaskTransitionToken transition) { + return Optional.empty(); + } + + @Override + public UserTaskTransitionToken newTransitionToken(String transitionId, UserTaskInstance userTaskInstance, Map data) { + UserTaskState state = userTaskInstance.getStatus(); + UserTaskTransition transition = transitions.stream().filter(e -> e.source().equals(state) && e.id().equals(transitionId)).findAny() + .orElseThrow(() -> new RuntimeException("Invalid transition " + transitionId + " from " + state)); + return new DefaultUserTaskTransitionToken(transition, data); + } + + @Override + public UserTaskTransitionToken newCompleteTransitionToken(UserTaskInstance userTaskInstance, Map data) { + return newTransitionToken("complete", userTaskInstance, data); + } + + @Override + public UserTaskTransitionToken newAbortTransitionToken(UserTaskInstance userTaskInstance, Map data) { + return newTransitionToken("fail", userTaskInstance, data); + } + + public static Optional activate(UserTaskInstance userTaskInstance, UserTaskTransitionToken token) { + return Optional.empty(); + } + + public static Optional claim(UserTaskInstance userTaskInstance, UserTaskTransitionToken token) { + return Optional.empty(); + } + + public static Optional release(UserTaskInstance userTaskInstance, UserTaskTransitionToken token) { + return Optional.empty(); + } + + public static Optional complete(UserTaskInstance userTaskInstance, UserTaskTransitionToken token) { + return Optional.empty(); + } + + public static Optional skip(UserTaskInstance userTaskInstance, UserTaskTransitionToken token) { + return Optional.empty(); + } + + public static Optional fail(UserTaskInstance userTaskInstance, UserTaskTransitionToken token) { + return Optional.empty(); + } +} diff --git a/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskTransitionToken.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskTransitionToken.java new file mode 100644 index 00000000000..303d9d8e80a --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTaskTransitionToken.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl.lifecycle; + +import java.util.Map; + +import org.kie.kogito.usertask.lifecycle.UserTaskTransition; +import org.kie.kogito.usertask.lifecycle.UserTaskTransitionToken; + +public class DefaultUserTaskTransitionToken implements UserTaskTransitionToken { + + private UserTaskTransition transition; + private Map data; + + public DefaultUserTaskTransitionToken(UserTaskTransition transition, Map data) { + this.transition = transition; + this.data = data; + } + + @Override + public UserTaskTransition transition() { + return transition; + } + + @Override + public Map data() { + return data; + } + +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Active.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTransition.java similarity index 50% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Active.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTransition.java index bd1cb5141c8..353d17148a3 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/workitem/Active.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/lifecycle/DefaultUserTransition.java @@ -16,48 +16,44 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.workitem; +package org.kie.kogito.usertask.impl.lifecycle; -import java.util.Arrays; -import java.util.List; +import org.kie.kogito.usertask.lifecycle.UserTaskState; +import org.kie.kogito.usertask.lifecycle.UserTaskTransition; +import org.kie.kogito.usertask.lifecycle.UserTaskTransitionExecutor; -import org.kie.kogito.process.workitem.LifeCyclePhase; +public class DefaultUserTransition implements UserTaskTransition { -/** - * Active life cycle phase that applies to any work item. - * It will set the status to "Ready" - * - * This is initial state so it can transition even if there is no phase set yet. - */ -public class Active implements LifeCyclePhase { - - public static final String ID = "active"; - public static final String STATUS = "Ready"; + private String id; + private UserTaskState source; + private UserTaskState target; + private UserTaskTransitionExecutor executor; - private List allowedTransitions = Arrays.asList(); + public DefaultUserTransition(String id, UserTaskState source, UserTaskState target, UserTaskTransitionExecutor executor) { + this.id = id; + this.source = source; + this.target = target; + this.executor = executor; + } @Override public String id() { - return ID; + return id; } @Override - public String status() { - return STATUS; + public UserTaskState source() { + return source; } @Override - public boolean isTerminating() { - return false; + public UserTaskState target() { + return target; } @Override - public boolean canTransition(LifeCyclePhase phase) { - if (phase == null) { - return true; - } - - return allowedTransitions.contains(phase.id()); + public UserTaskTransitionExecutor executor() { + return executor; } } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/DeadlineHelper.java b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java similarity index 97% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/DeadlineHelper.java rename to jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java index 08b852d9ca4..cb541a9c7e9 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/DeadlineHelper.java +++ b/jbpm/jbpm-usertask/src/main/java/org/kie/kogito/usertask/impl/model/DeadlineHelper.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.humantask; +package org.kie.kogito.usertask.impl.model; import java.time.Duration; import java.time.Instant; @@ -37,6 +37,9 @@ import org.kie.kogito.jobs.DurationExpirationTime; import org.kie.kogito.jobs.ExactExpirationTime; import org.kie.kogito.jobs.ExpirationTime; +import org.kie.kogito.usertask.model.DeadlineInfo; +import org.kie.kogito.usertask.model.Reassignment; +import org.kie.kogito.usertask.model.ScheduleInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jbpm/jbpm-usertask/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory b/jbpm/jbpm-usertask/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory new file mode 100644 index 00000000000..5c3b656775f --- /dev/null +++ b/jbpm/jbpm-usertask/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory @@ -0,0 +1 @@ +org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandlerFactory \ No newline at end of file diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/impl/humantask/DeadlineHelperTest.java b/jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java similarity index 98% rename from jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/impl/humantask/DeadlineHelperTest.java rename to jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java index 15e6f08cf89..0bf241c43bb 100644 --- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/impl/humantask/DeadlineHelperTest.java +++ b/jbpm/jbpm-usertask/src/test/java/org/kie/kogito/usertask/impl/model/DeadlineHelperTest.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.humantask; +package org.kie.kogito.usertask.impl.model; import java.time.Duration; import java.time.Period; @@ -27,9 +27,12 @@ import org.junit.jupiter.api.Test; import org.kie.kogito.jobs.ExpirationTime; +import org.kie.kogito.usertask.model.DeadlineInfo; +import org.kie.kogito.usertask.model.Reassignment; +import org.kie.kogito.usertask.model.ScheduleInfo; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.fail; public class DeadlineHelperTest { diff --git a/jbpm/pom.xml b/jbpm/pom.xml index 6129c935bc1..9f31c94d8a8 100755 --- a/jbpm/pom.xml +++ b/jbpm/pom.xml @@ -46,6 +46,7 @@ jbpm-flow-migration process-serialization-protobuf process-workitems + jbpm-usertask jbpm-tools jbpm-tests jbpm-deps-groups diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java index 115c7510d02..544e1f40225 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java @@ -18,14 +18,10 @@ */ package org.jbpm.flow.serialization.impl.marshallers.state; -import java.net.URI; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.Map; import java.util.UUID; -import java.util.function.Function; -import java.util.stream.Collectors; import org.jbpm.flow.serialization.MarshallerContextName; import org.jbpm.flow.serialization.MarshallerReaderContext; @@ -33,17 +29,9 @@ import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; import org.jbpm.flow.serialization.impl.ProtobufVariableReader; import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemImpl; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.humantask.Reassignment; import org.jbpm.ruleflow.instance.RuleFlowProcessInstance; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; import org.jbpm.workflow.instance.node.WorkItemNodeInstance; import org.kie.api.runtime.process.NodeInstance; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; @@ -68,48 +56,10 @@ public NodeInstance read(MarshallerReaderContext context, Any value) { try { ProtobufVariableReader varReader = new ProtobufVariableReader(context); WorkItemNodeInstanceContent content = value.unpack(WorkItemNodeInstanceContent.class); - WorkItemNodeInstance nodeInstance = instanceWorkItem(content); - if (nodeInstance instanceof HumanTaskNodeInstance) { - HumanTaskNodeInstance humanTaskNodeInstance = (HumanTaskNodeInstance) nodeInstance; - InternalHumanTaskWorkItem workItem = humanTaskNodeInstance.getWorkItem(); - Any workItemDataMessage = content.getWorkItemData(); - if (workItemDataMessage.is(HumanTaskWorkItemData.class)) { - HumanTaskWorkItemData workItemData = workItemDataMessage.unpack(HumanTaskWorkItemData.class); - humanTaskNodeInstance.getNotCompletedDeadlineTimers().putAll(buildDeadlines(workItemData.getCompletedDeadlinesMap())); - humanTaskNodeInstance.getNotCompletedReassigments().putAll(buildReassignments(workItemData.getCompletedReassigmentsMap())); - humanTaskNodeInstance.getNotStartedDeadlineTimers().putAll(buildDeadlines(workItemData.getStartDeadlinesMap())); - humanTaskNodeInstance.getNotStartedReassignments().putAll(buildReassignments(workItemData.getStartReassigmentsMap())); - - if (workItemData.hasTaskName()) { - workItem.setTaskName(workItemData.getTaskName()); - } - if (workItemData.hasTaskDescription()) { - workItem.setTaskDescription(workItemData.getTaskDescription()); - } - if (workItemData.hasTaskPriority()) { - workItem.setTaskPriority(workItemData.getTaskPriority()); - } - if (workItemData.hasTaskReferenceName()) { - workItem.setReferenceName(workItemData.getTaskReferenceName()); - } - if (workItemData.hasActualOwner()) { - workItem.setActualOwner(workItemData.getActualOwner()); - } - workItem.getAdminUsers().addAll(workItemData.getAdminUsersList()); - workItem.getAdminGroups().addAll(workItemData.getAdminGroupsList()); - workItem.getPotentialUsers().addAll(workItemData.getPotUsersList()); - workItem.getPotentialGroups().addAll(workItemData.getPotGroupsList()); - workItem.getExcludedUsers().addAll(workItemData.getExcludedUsersList()); - workItem.getComments().putAll(workItemData.getCommentsList().stream().map(this::buildComment).collect(Collectors.toMap(Comment::getId, Function.identity()))); - workItem.getAttachments().putAll(workItemData.getAttachmentsList().stream().map(this::buildAttachment).collect(Collectors.toMap(Attachment::getId, Function.identity()))); - - } - - } - + WorkItemNodeInstance nodeInstance = instanceWorkItem(); RuleFlowProcessInstance ruleFlowProcessInstance = context.get(MarshallerContextName.MARSHALLER_PROCESS_INSTANCE); nodeInstance.internalSetWorkItemId(content.getWorkItemId()); - InternalKogitoWorkItem workItem = (InternalKogitoWorkItem) nodeInstance.getWorkItem(); + InternalKogitoWorkItem workItem = nodeInstance.getWorkItem(); workItem.setId(content.getWorkItemId()); workItem.setProcessInstanceId(ruleFlowProcessInstance.getStringId()); workItem.setName(content.getName()); @@ -119,6 +69,12 @@ public NodeInstance read(MarshallerReaderContext context, Any value) { workItem.setPhaseId(content.getPhaseId()); workItem.setPhaseStatus(content.getPhaseStatus()); workItem.setStartDate(new Date(content.getStartDate())); + if (content.hasExternalReferenceId()) { + workItem.setExternalReferenceId(content.getExternalReferenceId()); + } + if (content.hasActualOwner()) { + workItem.setActualOwner(content.getActualOwner()); + } if (content.getCompleteDate() > 0) { workItem.setCompleteDate(new Date(content.getCompleteDate())); } @@ -138,59 +94,11 @@ public NodeInstance read(MarshallerReaderContext context, Any value) { } } - private WorkItemNodeInstance instanceWorkItem(WorkItemNodeInstanceContent content) { - if (content.hasWorkItemData()) { - Any workItemDataMessage = content.getWorkItemData(); - if (workItemDataMessage.is(HumanTaskWorkItemData.class)) { - HumanTaskNodeInstance nodeInstance = new HumanTaskNodeInstance(); - HumanTaskWorkItemImpl workItem = new HumanTaskWorkItemImpl(); - nodeInstance.internalSetWorkItem(workItem); - return nodeInstance; - } else { - throw new ProcessInstanceMarshallerException("Don't know which type of work item is"); - } - } else { - WorkItemNodeInstance nodeInstance = new WorkItemNodeInstance(); - KogitoWorkItemImpl workItem = new KogitoWorkItemImpl(); - workItem.setId(UUID.randomUUID().toString()); - nodeInstance.internalSetWorkItem(workItem); - return nodeInstance; - } - } - - private Comment buildComment(KogitoWorkItemsProtobuf.Comment comment) { - Comment result = new Comment(comment.getId(), comment.getUpdatedBy()); - result.setContent(comment.getContent()); - result.setUpdatedAt(new Date(comment.getUpdatedAt())); - return result; - } - - private Attachment buildAttachment(KogitoWorkItemsProtobuf.Attachment attachment) { - Attachment result = new Attachment(attachment.getId(), attachment.getUpdatedBy()); - result.setContent(URI.create(attachment.getContent())); - result.setUpdatedAt(new Date(attachment.getUpdatedAt())); - result.setName(attachment.getName()); - return result; - } - - private Map> buildDeadlines(Map deadlinesProtobuf) { - Map> deadlines = new HashMap<>(); - for (Map.Entry entry : deadlinesProtobuf.entrySet()) { - Map notification = new HashMap<>(); - for (Map.Entry pair : entry.getValue().getContentMap().entrySet()) { - notification.put(pair.getKey(), pair.getValue()); - } - deadlines.put(entry.getKey(), notification); - } - return deadlines; - } - - private Map buildReassignments(Map reassignmentsProtobuf) { - Map reassignments = new HashMap<>(); - for (Map.Entry entry : reassignmentsProtobuf.entrySet()) { - reassignments.put(entry.getKey(), new Reassignment(entry.getValue().getUsersList().stream().collect(Collectors - .toSet()), entry.getValue().getGroupsList().stream().collect(Collectors.toSet()))); - } - return reassignments; + private WorkItemNodeInstance instanceWorkItem() { + WorkItemNodeInstance nodeInstance = new WorkItemNodeInstance(); + KogitoWorkItemImpl workItem = new KogitoWorkItemImpl(); + workItem.setId(UUID.randomUUID().toString()); + nodeInstance.internalSetWorkItem(workItem); + return nodeInstance; } } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java index 50609b1ffd3..1c28f5b9bb8 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java @@ -19,26 +19,16 @@ package org.jbpm.flow.serialization.impl.marshallers.state; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.jbpm.flow.serialization.MarshallerWriterContext; import org.jbpm.flow.serialization.NodeInstanceWriter; import org.jbpm.flow.serialization.impl.ProtobufVariableWriter; import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData; -import org.jbpm.process.instance.impl.humantask.Reassignment; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; import org.jbpm.workflow.instance.node.WorkItemNodeInstance; import org.kie.api.runtime.process.NodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; -import com.google.protobuf.Any; import com.google.protobuf.GeneratedMessageV3.Builder; public class WorkItemNodeInstanceWriter implements NodeInstanceWriter { @@ -79,126 +69,15 @@ public Builder write(MarshallerWriterContext context, NodeInstance value) { builder.setCompleteDate(workItem.getCompleteDate().getTime()); } - if (nodeInstance instanceof HumanTaskNodeInstance) { - builder.setWorkItemData(Any.pack(buildHumanTaskWorkItemData((HumanTaskNodeInstance) nodeInstance, (HumanTaskWorkItem) nodeInstance.getWorkItem()))); - } - return builder; - } - - private HumanTaskWorkItemData buildHumanTaskWorkItemData(HumanTaskNodeInstance nodeInstance, HumanTaskWorkItem workItem) { - HumanTaskWorkItemData.Builder builder = HumanTaskWorkItemData.newBuilder(); - - if (workItem.getTaskPriority() != null) { - builder.setTaskPriority(workItem.getTaskPriority()); - } - - if (workItem.getReferenceName() != null) { - builder.setTaskReferenceName(workItem.getReferenceName()); - } - if (workItem.getTaskDescription() != null) { - builder.setTaskDescription(workItem.getTaskDescription()); - } - if (workItem.getActualOwner() != null) { builder.setActualOwner(workItem.getActualOwner()); } - if (workItem.getTaskName() != null) { - builder.setTaskName(workItem.getTaskName()); - } - - if (workItem.getPotentialUsers() != null) { - builder.addAllPotUsers(workItem.getPotentialUsers()); - } - - if (workItem.getPotentialGroups() != null) { - builder.addAllPotGroups(workItem.getPotentialGroups()); - } - - if (workItem.getExcludedUsers() != null) { - builder.addAllExcludedUsers(workItem.getExcludedUsers()); - } - - if (workItem.getAdminUsers() != null) { - builder.addAllAdminUsers(workItem.getAdminUsers()); - } - - if (workItem.getAdminGroups() != null) { - builder.addAllAdminGroups(workItem.getAdminGroups()); - } - - if (workItem.getComments() != null) { - builder.addAllComments(buildComments(workItem.getComments().values())); + if (workItem.getExternalReferenceId() != null) { + builder.setExternalReferenceId(workItem.getExternalReferenceId()); } - if (workItem.getAttachments() != null) { - builder.addAllAttachments(buildAttachments(workItem.getAttachments().values())); - } - - if (nodeInstance.getNotStartedDeadlineTimers() != null) { - builder.putAllStartDeadlines(buildDeadlines(nodeInstance.getNotStartedDeadlineTimers())); - } - - if (nodeInstance.getNotStartedReassignments() != null) { - builder.putAllStartReassigments(buildReassignments(nodeInstance.getNotStartedReassignments())); - } - - if (nodeInstance.getNotCompletedDeadlineTimers() != null) { - builder.putAllCompletedDeadlines(buildDeadlines(nodeInstance.getNotCompletedDeadlineTimers())); - } - - if (nodeInstance.getNotCompletedReassigments() != null) { - builder.putAllCompletedReassigments(buildReassignments(nodeInstance.getNotCompletedReassigments())); - } - - return builder.build(); - } - - private List buildComments(Iterable comments) { - List commentsProtobuf = new ArrayList<>(); - for (Comment comment : comments) { - KogitoWorkItemsProtobuf.Comment workItemComment = KogitoWorkItemsProtobuf.Comment.newBuilder() - .setId(comment.getId().toString()) - .setContent(comment.getContent()) - .setUpdatedBy(comment.getUpdatedBy()) - .setUpdatedAt(comment.getUpdatedAt().getTime()) - .build(); - commentsProtobuf.add(workItemComment); - } - return commentsProtobuf; - } - - private List buildAttachments(Iterable attachments) { - List attachmentProtobuf = new ArrayList<>(); - for (Attachment attachment : attachments) { - KogitoWorkItemsProtobuf.Attachment workItemAttachment = KogitoWorkItemsProtobuf.Attachment.newBuilder() - .setId(attachment.getId().toString()).setContent(attachment.getContent().toString()) - .setUpdatedBy(attachment.getUpdatedBy()).setUpdatedAt(attachment.getUpdatedAt().getTime()) - .setName(attachment.getName()) - .build(); - attachmentProtobuf.add(workItemAttachment); - } - return attachmentProtobuf; - } - - private Map buildDeadlines(Map> deadlines) { - Map deadlinesProtobuf = new HashMap<>(); - for (Map.Entry> entry : deadlines.entrySet()) { - KogitoWorkItemsProtobuf.Deadline.Builder builder = KogitoWorkItemsProtobuf.Deadline.newBuilder(); - entry.getValue().forEach((k, v) -> builder.putContent(k, v.toString())); - deadlinesProtobuf.put(entry.getKey(), builder.build()); - } - return deadlinesProtobuf; + return builder; } - private Map buildReassignments(Map reassignments) { - Map reassignmentsProtobuf = new HashMap<>(); - for (Map.Entry entry : reassignments.entrySet()) { - KogitoWorkItemsProtobuf.Reassignment.Builder builder = KogitoWorkItemsProtobuf.Reassignment.newBuilder(); - builder.addAllGroups(entry.getValue().getPotentialGroups()); - builder.addAllUsers(entry.getValue().getPotentialUsers()); - reassignmentsProtobuf.put(entry.getKey(), builder.build()); - } - return reassignmentsProtobuf; - } } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoNodeInstanceContentsProtobuf.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoNodeInstanceContentsProtobuf.java index df604aff015..28878ffc329 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoNodeInstanceContentsProtobuf.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoNodeInstanceContentsProtobuf.java @@ -1586,6 +1586,50 @@ java.lang.String getTimerInstanceReferenceOrDefault( */ java.lang.String getTimerInstanceReferenceOrThrow( java.lang.String key); + + /** + * optional string actual_owner = 14; + * + * @return Whether the actualOwner field is set. + */ + boolean hasActualOwner(); + + /** + * optional string actual_owner = 14; + * + * @return The actualOwner. + */ + java.lang.String getActualOwner(); + + /** + * optional string actual_owner = 14; + * + * @return The bytes for actualOwner. + */ + com.google.protobuf.ByteString + getActualOwnerBytes(); + + /** + * optional string external_reference_id = 15; + * + * @return Whether the externalReferenceId field is set. + */ + boolean hasExternalReferenceId(); + + /** + * optional string external_reference_id = 15; + * + * @return The externalReferenceId. + */ + java.lang.String getExternalReferenceId(); + + /** + * optional string external_reference_id = 15; + * + * @return The bytes for externalReferenceId. + */ + com.google.protobuf.ByteString + getExternalReferenceIdBytes(); } /** @@ -1612,6 +1656,8 @@ private WorkItemNodeInstanceContent() { phaseId_ = ""; phaseStatus_ = ""; name_ = ""; + actualOwner_ = ""; + externalReferenceId_ = ""; } @java.lang.Override @@ -2226,6 +2272,112 @@ public java.lang.String getTimerInstanceReferenceOrThrow( return map.get(key); } + public static final int ACTUAL_OWNER_FIELD_NUMBER = 14; + @SuppressWarnings("serial") + private volatile java.lang.Object actualOwner_ = ""; + + /** + * optional string actual_owner = 14; + * + * @return Whether the actualOwner field is set. + */ + @java.lang.Override + public boolean hasActualOwner() { + return ((bitField0_ & 0x00000080) != 0); + } + + /** + * optional string actual_owner = 14; + * + * @return The actualOwner. + */ + @java.lang.Override + public java.lang.String getActualOwner() { + java.lang.Object ref = actualOwner_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actualOwner_ = s; + return s; + } + } + + /** + * optional string actual_owner = 14; + * + * @return The bytes for actualOwner. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getActualOwnerBytes() { + java.lang.Object ref = actualOwner_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actualOwner_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int EXTERNAL_REFERENCE_ID_FIELD_NUMBER = 15; + @SuppressWarnings("serial") + private volatile java.lang.Object externalReferenceId_ = ""; + + /** + * optional string external_reference_id = 15; + * + * @return Whether the externalReferenceId field is set. + */ + @java.lang.Override + public boolean hasExternalReferenceId() { + return ((bitField0_ & 0x00000100) != 0); + } + + /** + * optional string external_reference_id = 15; + * + * @return The externalReferenceId. + */ + @java.lang.Override + public java.lang.String getExternalReferenceId() { + java.lang.Object ref = externalReferenceId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + externalReferenceId_ = s; + return s; + } + } + + /** + * optional string external_reference_id = 15; + * + * @return The bytes for externalReferenceId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getExternalReferenceIdBytes() { + java.lang.Object ref = externalReferenceId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + externalReferenceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -2285,6 +2437,12 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) internalGetTimerInstanceReference(), TimerInstanceReferenceDefaultEntryHolder.defaultEntry, 13); + if (((bitField0_ & 0x00000080) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 14, actualOwner_); + } + if (((bitField0_ & 0x00000100) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 15, externalReferenceId_); + } getUnknownFields().writeTo(output); } @@ -2350,6 +2508,12 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(13, timerInstanceReference__); } + if (((bitField0_ & 0x00000080) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, actualOwner_); + } + if (((bitField0_ & 0x00000100) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(15, externalReferenceId_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -2430,6 +2594,20 @@ public boolean equals(final java.lang.Object obj) { if (!internalGetTimerInstanceReference().equals( other.internalGetTimerInstanceReference())) return false; + if (hasActualOwner() != other.hasActualOwner()) + return false; + if (hasActualOwner()) { + if (!getActualOwner() + .equals(other.getActualOwner())) + return false; + } + if (hasExternalReferenceId() != other.hasExternalReferenceId()) + return false; + if (hasExternalReferenceId()) { + if (!getExternalReferenceId() + .equals(other.getExternalReferenceId())) + return false; + } if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; @@ -2492,6 +2670,14 @@ public int hashCode() { hash = (37 * hash) + TIMER_INSTANCE_REFERENCE_FIELD_NUMBER; hash = (53 * hash) + internalGetTimerInstanceReference().hashCode(); } + if (hasActualOwner()) { + hash = (37 * hash) + ACTUAL_OWNER_FIELD_NUMBER; + hash = (53 * hash) + getActualOwner().hashCode(); + } + if (hasExternalReferenceId()) { + hash = (37 * hash) + EXTERNAL_REFERENCE_ID_FIELD_NUMBER; + hash = (53 * hash) + getExternalReferenceId().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -2703,6 +2889,8 @@ public Builder clear() { workItemDataBuilder_ = null; } internalGetMutableTimerInstanceReference().clear(); + actualOwner_ = ""; + externalReferenceId_ = ""; return this; } @@ -2806,6 +2994,14 @@ private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoNodeInstan result.timerInstanceReference_ = internalGetTimerInstanceReference(); result.timerInstanceReference_.makeImmutable(); } + if (((from_bitField0_ & 0x00002000) != 0)) { + result.actualOwner_ = actualOwner_; + to_bitField0_ |= 0x00000080; + } + if (((from_bitField0_ & 0x00004000) != 0)) { + result.externalReferenceId_ = externalReferenceId_; + to_bitField0_ |= 0x00000100; + } result.bitField0_ |= to_bitField0_; } @@ -2960,6 +3156,16 @@ public Builder mergeFrom(org.jbpm.flow.serialization.protobuf.KogitoNodeInstance internalGetMutableTimerInstanceReference().mergeFrom( other.internalGetTimerInstanceReference()); bitField0_ |= 0x00001000; + if (other.hasActualOwner()) { + actualOwner_ = other.actualOwner_; + bitField0_ |= 0x00002000; + onChanged(); + } + if (other.hasExternalReferenceId()) { + externalReferenceId_ = other.externalReferenceId_; + bitField0_ |= 0x00004000; + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -3073,6 +3279,16 @@ public Builder mergeFrom( bitField0_ |= 0x00001000; break; } // case 106 + case 114: { + actualOwner_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00002000; + break; + } // case 114 + case 122: { + externalReferenceId_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00004000; + break; + } // case 122 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -4635,6 +4851,196 @@ public Builder putAllTimerInstanceReference( return this; } + private java.lang.Object actualOwner_ = ""; + + /** + * optional string actual_owner = 14; + * + * @return Whether the actualOwner field is set. + */ + public boolean hasActualOwner() { + return ((bitField0_ & 0x00002000) != 0); + } + + /** + * optional string actual_owner = 14; + * + * @return The actualOwner. + */ + public java.lang.String getActualOwner() { + java.lang.Object ref = actualOwner_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actualOwner_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + + /** + * optional string actual_owner = 14; + * + * @return The bytes for actualOwner. + */ + public com.google.protobuf.ByteString + getActualOwnerBytes() { + java.lang.Object ref = actualOwner_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actualOwner_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + /** + * optional string actual_owner = 14; + * + * @param value The actualOwner to set. + * @return This builder for chaining. + */ + public Builder setActualOwner( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + actualOwner_ = value; + bitField0_ |= 0x00002000; + onChanged(); + return this; + } + + /** + * optional string actual_owner = 14; + * + * @return This builder for chaining. + */ + public Builder clearActualOwner() { + actualOwner_ = getDefaultInstance().getActualOwner(); + bitField0_ = (bitField0_ & ~0x00002000); + onChanged(); + return this; + } + + /** + * optional string actual_owner = 14; + * + * @param value The bytes for actualOwner to set. + * @return This builder for chaining. + */ + public Builder setActualOwnerBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + actualOwner_ = value; + bitField0_ |= 0x00002000; + onChanged(); + return this; + } + + private java.lang.Object externalReferenceId_ = ""; + + /** + * optional string external_reference_id = 15; + * + * @return Whether the externalReferenceId field is set. + */ + public boolean hasExternalReferenceId() { + return ((bitField0_ & 0x00004000) != 0); + } + + /** + * optional string external_reference_id = 15; + * + * @return The externalReferenceId. + */ + public java.lang.String getExternalReferenceId() { + java.lang.Object ref = externalReferenceId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + externalReferenceId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + + /** + * optional string external_reference_id = 15; + * + * @return The bytes for externalReferenceId. + */ + public com.google.protobuf.ByteString + getExternalReferenceIdBytes() { + java.lang.Object ref = externalReferenceId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + externalReferenceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + /** + * optional string external_reference_id = 15; + * + * @param value The externalReferenceId to set. + * @return This builder for chaining. + */ + public Builder setExternalReferenceId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + externalReferenceId_ = value; + bitField0_ |= 0x00004000; + onChanged(); + return this; + } + + /** + * optional string external_reference_id = 15; + * + * @return This builder for chaining. + */ + public Builder clearExternalReferenceId() { + externalReferenceId_ = getDefaultInstance().getExternalReferenceId(); + bitField0_ = (bitField0_ & ~0x00004000); + onChanged(); + return this; + } + + /** + * optional string external_reference_id = 15; + * + * @param value The bytes for externalReferenceId to set. + * @return This builder for chaining. + */ + public Builder setExternalReferenceIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + externalReferenceId_ = value; + bitField0_ |= 0x00004000; + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -18058,7 +18464,7 @@ public org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.A "leSetNodeInstanceContent.TimerInstanceRe" + "ferenceEntry\032=\n\033TimerInstanceReferenceEn" + "try\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B\022\n\020_" + - "rule_flow_group\"\377\005\n\033WorkItemNodeInstance" + + "rule_flow_group\"\351\006\n\033WorkItemNodeInstance" + "Content\022\024\n\014work_item_id\030\001 \001(\t\022\031\n\021timer_i" + "nstance_id\030\002 \003(\t\022/\n\"error_handling_proce" + "ss_instance_id\030\003 \001(\tH\000\210\001\001\022\r\n\005state\030\004 \001(\005" + @@ -18072,85 +18478,88 @@ public org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.A "oogle.protobuf.AnyH\006\210\001\001\022\177\n\030timer_instanc" + "e_reference\030\r \003(\0132].org.jbpm.flow.serial" + "ization.protobuf.WorkItemNodeInstanceCon" + - "tent.TimerInstanceReferenceEntry\032=\n\033Time" + - "rInstanceReferenceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005" + - "value\030\002 \001(\t:\0028\001B%\n#_error_handling_proce" + - "ss_instance_idB\013\n\t_phase_idB\017\n\r_phase_st" + - "atusB\007\n\005_nameB\r\n\013_start_dateB\020\n\016_complet" + - "e_dateB\021\n\017_work_item_data\"\303\002\n#LambdaSubP" + - "rocessNodeInstanceContent\022 \n\023process_ins" + - "tance_id\030\001 \001(\tH\000\210\001\001\022\031\n\021timer_instance_id" + - "\030\002 \003(\t\022\207\001\n\030timer_instance_reference\030\003 \003(" + - "\0132e.org.jbpm.flow.serialization.protobuf" + - ".LambdaSubProcessNodeInstanceContent.Tim" + - "erInstanceReferenceEntry\032=\n\033TimerInstanc" + - "eReferenceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 " + - "\001(\t:\0028\001B\026\n\024_process_instance_id\"\267\002\n\035SubP" + - "rocessNodeInstanceContent\022 \n\023process_ins" + - "tance_id\030\001 \001(\tH\000\210\001\001\022\031\n\021timer_instance_id" + - "\030\002 \003(\t\022\201\001\n\030timer_instance_reference\030\003 \003(" + - "\0132_.org.jbpm.flow.serialization.protobuf" + - ".SubProcessNodeInstanceContent.TimerInst" + - "anceReferenceEntry\032=\n\033TimerInstanceRefer" + - "enceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028" + - "\001B\026\n\024_process_instance_id\"\373\001\n\034MilestoneN" + - "odeInstanceContent\022\031\n\021timer_instance_id\030" + - "\001 \003(\t\022\200\001\n\030timer_instance_reference\030\002 \003(\013" + - "2^.org.jbpm.flow.serialization.protobuf." + - "MilestoneNodeInstanceContent.TimerInstan" + - "ceReferenceEntry\032=\n\033TimerInstanceReferen" + - "ceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"" + - "\032\n\030EventNodeInstanceContent\">\n\030TimerNode" + - "InstanceContent\022\025\n\010timer_id\030\001 \001(\tH\000\210\001\001B\013" + - "\n\t_timer_id\"\310\001\n\027JoinNodeInstanceContent\022" + - "Z\n\007trigger\030\001 \003(\0132I.org.jbpm.flow.seriali" + - "zation.protobuf.JoinNodeInstanceContent." + - "JoinTrigger\032Q\n\013JoinTrigger\022\024\n\007node_id\030\001 " + - "\001(\tH\000\210\001\001\022\024\n\007counter\030\002 \001(\005H\001\210\001\001B\n\n\010_node_" + - "idB\n\n\010_counter\"\362\001\n\030StateNodeInstanceCont" + - "ent\022\031\n\021timer_instance_id\030\001 \003(\t\022|\n\030timer_" + - "instance_reference\030\002 \003(\0132Z.org.jbpm.flow" + - ".serialization.protobuf.StateNodeInstanc" + - "eContent.TimerInstanceReferenceEntry\032=\n\033" + - "TimerInstanceReferenceEntry\022\013\n\003key\030\001 \001(\t" + - "\022\r\n\005value\030\002 \001(\t:\0028\001\"\321\002\n#CompositeContext" + - "NodeInstanceContent\022\031\n\021timer_instance_id" + - "\030\001 \003(\t\022F\n\007context\030\002 \001(\01325.org.jbpm.flow." + - "serialization.protobuf.WorkflowContext\022\207" + - "\001\n\030timer_instance_reference\030\003 \003(\0132e.org." + - "jbpm.flow.serialization.protobuf.Composi" + - "teContextNodeInstanceContent.TimerInstan" + - "ceReferenceEntry\032=\n\033TimerInstanceReferen" + - "ceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"" + - "\276\002\n\032DynamicNodeInstanceContent\022\031\n\021timer_" + - "instance_id\030\001 \003(\t\022F\n\007context\030\002 \001(\01325.org" + - ".jbpm.flow.serialization.protobuf.Workfl" + - "owContext\022~\n\030timer_instance_reference\030\003 " + - "\003(\0132\\.org.jbpm.flow.serialization.protob" + - "uf.DynamicNodeInstanceContent.TimerInsta" + - "nceReferenceEntry\032=\n\033TimerInstanceRefere" + - "nceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001" + - "\"\317\002\n\"EventSubProcessNodeInstanceContent\022" + - "\031\n\021timer_instance_id\030\001 \003(\t\022F\n\007context\030\002 " + - "\001(\01325.org.jbpm.flow.serialization.protob" + - "uf.WorkflowContext\022\206\001\n\030timer_instance_re" + - "ference\030\003 \003(\0132d.org.jbpm.flow.serializat" + - "ion.protobuf.EventSubProcessNodeInstance" + - "Content.TimerInstanceReferenceEntry\032=\n\033T" + - "imerInstanceReferenceEntry\022\013\n\003key\030\001 \001(\t\022" + - "\r\n\005value\030\002 \001(\t:\0028\001\"\214\003\n\032ForEachNodeInstan" + - "ceContent\022\031\n\021timer_instance_id\030\001 \003(\t\022F\n\007" + - "context\030\002 \001(\01325.org.jbpm.flow.serializat" + - "ion.protobuf.WorkflowContext\022\026\n\016totalIns" + - "tances\030\003 \001(\005\022\031\n\021executedInstances\030\004 \001(\005\022" + - "\031\n\021hasAsyncInstances\030\005 \001(\010\022~\n\030timer_inst" + - "ance_reference\030\006 \003(\0132\\.org.jbpm.flow.ser" + - "ialization.protobuf.ForEachNodeInstanceC" + - "ontent.TimerInstanceReferenceEntry\032=\n\033Ti" + - "merInstanceReferenceEntry\022\013\n\003key\030\001 \001(\t\022\r" + - "\n\005value\030\002 \001(\t:\0028\001\"/\n\035AsyncEventNodeInsta" + - "nceContent\022\016\n\006job_id\030\001 \001(\tB$B\"KogitoNode" + - "InstanceContentsProtobufb\006proto3" + "tent.TimerInstanceReferenceEntry\022\031\n\014actu" + + "al_owner\030\016 \001(\tH\007\210\001\001\022\"\n\025external_referenc" + + "e_id\030\017 \001(\tH\010\210\001\001\032=\n\033TimerInstanceReferenc" + + "eEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B%" + + "\n#_error_handling_process_instance_idB\013\n" + + "\t_phase_idB\017\n\r_phase_statusB\007\n\005_nameB\r\n\013" + + "_start_dateB\020\n\016_complete_dateB\021\n\017_work_i" + + "tem_dataB\017\n\r_actual_ownerB\030\n\026_external_r" + + "eference_id\"\303\002\n#LambdaSubProcessNodeInst" + + "anceContent\022 \n\023process_instance_id\030\001 \001(\t" + + "H\000\210\001\001\022\031\n\021timer_instance_id\030\002 \003(\t\022\207\001\n\030tim" + + "er_instance_reference\030\003 \003(\0132e.org.jbpm.f" + + "low.serialization.protobuf.LambdaSubProc" + + "essNodeInstanceContent.TimerInstanceRefe" + + "renceEntry\032=\n\033TimerInstanceReferenceEntr" + + "y\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B\026\n\024_pr" + + "ocess_instance_id\"\267\002\n\035SubProcessNodeInst" + + "anceContent\022 \n\023process_instance_id\030\001 \001(\t" + + "H\000\210\001\001\022\031\n\021timer_instance_id\030\002 \003(\t\022\201\001\n\030tim" + + "er_instance_reference\030\003 \003(\0132_.org.jbpm.f" + + "low.serialization.protobuf.SubProcessNod" + + "eInstanceContent.TimerInstanceReferenceE" + + "ntry\032=\n\033TimerInstanceReferenceEntry\022\013\n\003k" + + "ey\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B\026\n\024_process_" + + "instance_id\"\373\001\n\034MilestoneNodeInstanceCon" + + "tent\022\031\n\021timer_instance_id\030\001 \003(\t\022\200\001\n\030time" + + "r_instance_reference\030\002 \003(\0132^.org.jbpm.fl" + + "ow.serialization.protobuf.MilestoneNodeI" + + "nstanceContent.TimerInstanceReferenceEnt" + + "ry\032=\n\033TimerInstanceReferenceEntry\022\013\n\003key" + + "\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\032\n\030EventNodeIn" + + "stanceContent\">\n\030TimerNodeInstanceConten" + + "t\022\025\n\010timer_id\030\001 \001(\tH\000\210\001\001B\013\n\t_timer_id\"\310\001" + + "\n\027JoinNodeInstanceContent\022Z\n\007trigger\030\001 \003" + + "(\0132I.org.jbpm.flow.serialization.protobu" + + "f.JoinNodeInstanceContent.JoinTrigger\032Q\n" + + "\013JoinTrigger\022\024\n\007node_id\030\001 \001(\tH\000\210\001\001\022\024\n\007co" + + "unter\030\002 \001(\005H\001\210\001\001B\n\n\010_node_idB\n\n\010_counter" + + "\"\362\001\n\030StateNodeInstanceContent\022\031\n\021timer_i" + + "nstance_id\030\001 \003(\t\022|\n\030timer_instance_refer" + + "ence\030\002 \003(\0132Z.org.jbpm.flow.serialization" + + ".protobuf.StateNodeInstanceContent.Timer" + + "InstanceReferenceEntry\032=\n\033TimerInstanceR" + + "eferenceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(" + + "\t:\0028\001\"\321\002\n#CompositeContextNodeInstanceCo" + + "ntent\022\031\n\021timer_instance_id\030\001 \003(\t\022F\n\007cont" + + "ext\030\002 \001(\01325.org.jbpm.flow.serialization." + + "protobuf.WorkflowContext\022\207\001\n\030timer_insta" + + "nce_reference\030\003 \003(\0132e.org.jbpm.flow.seri" + + "alization.protobuf.CompositeContextNodeI" + + "nstanceContent.TimerInstanceReferenceEnt" + + "ry\032=\n\033TimerInstanceReferenceEntry\022\013\n\003key" + + "\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\276\002\n\032DynamicNod" + + "eInstanceContent\022\031\n\021timer_instance_id\030\001 " + + "\003(\t\022F\n\007context\030\002 \001(\01325.org.jbpm.flow.ser" + + "ialization.protobuf.WorkflowContext\022~\n\030t" + + "imer_instance_reference\030\003 \003(\0132\\.org.jbpm" + + ".flow.serialization.protobuf.DynamicNode" + + "InstanceContent.TimerInstanceReferenceEn" + + "try\032=\n\033TimerInstanceReferenceEntry\022\013\n\003ke" + + "y\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\317\002\n\"EventSubP" + + "rocessNodeInstanceContent\022\031\n\021timer_insta" + + "nce_id\030\001 \003(\t\022F\n\007context\030\002 \001(\01325.org.jbpm" + + ".flow.serialization.protobuf.WorkflowCon" + + "text\022\206\001\n\030timer_instance_reference\030\003 \003(\0132" + + "d.org.jbpm.flow.serialization.protobuf.E" + + "ventSubProcessNodeInstanceContent.TimerI" + + "nstanceReferenceEntry\032=\n\033TimerInstanceRe" + + "ferenceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t" + + ":\0028\001\"\214\003\n\032ForEachNodeInstanceContent\022\031\n\021t" + + "imer_instance_id\030\001 \003(\t\022F\n\007context\030\002 \001(\0132" + + "5.org.jbpm.flow.serialization.protobuf.W" + + "orkflowContext\022\026\n\016totalInstances\030\003 \001(\005\022\031" + + "\n\021executedInstances\030\004 \001(\005\022\031\n\021hasAsyncIns" + + "tances\030\005 \001(\010\022~\n\030timer_instance_reference" + + "\030\006 \003(\0132\\.org.jbpm.flow.serialization.pro" + + "tobuf.ForEachNodeInstanceContent.TimerIn" + + "stanceReferenceEntry\032=\n\033TimerInstanceRef" + + "erenceEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" + + "\0028\001\"/\n\035AsyncEventNodeInstanceContent\022\016\n\006" + + "job_id\030\001 \001(\tB$B\"KogitoNodeInstanceConten" + + "tsProtobufb\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -18173,7 +18582,7 @@ public org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.A internal_static_org_jbpm_flow_serialization_protobuf_WorkItemNodeInstanceContent_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_org_jbpm_flow_serialization_protobuf_WorkItemNodeInstanceContent_descriptor, new java.lang.String[] { "WorkItemId", "TimerInstanceId", "ErrorHandlingProcessInstanceId", "State", "Variable", "Result", "PhaseId", "PhaseStatus", "Name", "StartDate", - "CompleteDate", "WorkItemData", "TimerInstanceReference", }); + "CompleteDate", "WorkItemData", "TimerInstanceReference", "ActualOwner", "ExternalReferenceId", }); internal_static_org_jbpm_flow_serialization_protobuf_WorkItemNodeInstanceContent_TimerInstanceReferenceEntry_descriptor = internal_static_org_jbpm_flow_serialization_protobuf_WorkItemNodeInstanceContent_descriptor.getNestedTypes().get(0); internal_static_org_jbpm_flow_serialization_protobuf_WorkItemNodeInstanceContent_TimerInstanceReferenceEntry_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoWorkItemsProtobuf.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoWorkItemsProtobuf.java index fac37c8b677..a48b5b93067 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoWorkItemsProtobuf.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/protobuf/KogitoWorkItemsProtobuf.java @@ -309,218 +309,6 @@ public interface HumanTaskWorkItemDataOrBuilder extends */ com.google.protobuf.ByteString getTaskReferenceNameBytes(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - java.util.List - getCommentsList(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment getComments(int index); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - int getCommentsCount(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - java.util.List - getCommentsOrBuilderList(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.CommentOrBuilder getCommentsOrBuilder( - int index); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - java.util.List - getAttachmentsList(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment getAttachments(int index); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - int getAttachmentsCount(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - java.util.List - getAttachmentsOrBuilderList(); - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.AttachmentOrBuilder getAttachmentsOrBuilder( - int index); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - int getStartDeadlinesCount(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - boolean containsStartDeadlines( - java.lang.String key); - - /** - * Use {@link #getStartDeadlinesMap()} instead. - */ - @java.lang.Deprecated - java.util.Map - getStartDeadlines(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - java.util.Map - getStartDeadlinesMap(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getStartDeadlinesOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline defaultValue); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getStartDeadlinesOrThrow( - java.lang.String key); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - int getCompletedDeadlinesCount(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - boolean containsCompletedDeadlines( - java.lang.String key); - - /** - * Use {@link #getCompletedDeadlinesMap()} instead. - */ - @java.lang.Deprecated - java.util.Map - getCompletedDeadlines(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - java.util.Map - getCompletedDeadlinesMap(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getCompletedDeadlinesOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline defaultValue); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getCompletedDeadlinesOrThrow( - java.lang.String key); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - int getStartReassigmentsCount(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - boolean containsStartReassigments( - java.lang.String key); - - /** - * Use {@link #getStartReassigmentsMap()} instead. - */ - @java.lang.Deprecated - java.util.Map - getStartReassigments(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - java.util.Map - getStartReassigmentsMap(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getStartReassigmentsOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment defaultValue); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getStartReassigmentsOrThrow( - java.lang.String key); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - int getCompletedReassigmentsCount(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - boolean containsCompletedReassigments( - java.lang.String key); - - /** - * Use {@link #getCompletedReassigmentsMap()} instead. - */ - @java.lang.Deprecated - java.util.Map - getCompletedReassigments(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - java.util.Map - getCompletedReassigmentsMap(); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getCompletedReassigmentsOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment defaultValue); - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getCompletedReassigmentsOrThrow( - java.lang.String key); } /** @@ -553,8 +341,6 @@ private HumanTaskWorkItemData() { adminGroups_ = com.google.protobuf.LazyStringArrayList.emptyList(); taskReferenceName_ = ""; - comments_ = java.util.Collections.emptyList(); - attachments_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -569,25 +355,6 @@ protected java.lang.Object newInstance( return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_descriptor; } - @SuppressWarnings({ "rawtypes" }) - @java.lang.Override - protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( - int number) { - switch (number) { - case 13: - return internalGetStartDeadlines(); - case 14: - return internalGetCompletedDeadlines(); - case 15: - return internalGetStartReassigments(); - case 16: - return internalGetCompletedReassigments(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { @@ -1088,540 +855,54 @@ public java.lang.String getTaskReferenceName() { } } - public static final int COMMENTS_FIELD_NUMBER = 11; - @SuppressWarnings("serial") - private java.util.List comments_; - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - @java.lang.Override - public java.util.List getCommentsList() { - return comments_; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - @java.lang.Override - public java.util.List - getCommentsOrBuilderList() { - return comments_; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - @java.lang.Override - public int getCommentsCount() { - return comments_.size(); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment getComments(int index) { - return comments_.get(index); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.CommentOrBuilder getCommentsOrBuilder( - int index) { - return comments_.get(index); - } - - public static final int ATTACHMENTS_FIELD_NUMBER = 12; - @SuppressWarnings("serial") - private java.util.List attachments_; - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - @java.lang.Override - public java.util.List getAttachmentsList() { - return attachments_; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - @java.lang.Override - public java.util.List - getAttachmentsOrBuilderList() { - return attachments_; - } + private byte memoizedIsInitialized = -1; - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ @java.lang.Override - public int getAttachmentsCount() { - return attachments_.size(); - } + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment getAttachments(int index) { - return attachments_.get(index); + memoizedIsInitialized = 1; + return true; } - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.AttachmentOrBuilder getAttachmentsOrBuilder( - int index) { - return attachments_.get(index); - } - - public static final int START_DEADLINES_FIELD_NUMBER = 13; - - private static final class StartDeadlinesDefaultEntryHolder { - static final com.google.protobuf.MapEntry defaultEntry = - com.google.protobuf.MapEntry. newDefaultInstance( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_StartDeadlinesEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.MESSAGE, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.getDefaultInstance()); - } - - @SuppressWarnings("serial") - private com.google.protobuf.MapField startDeadlines_; - - private com.google.protobuf.MapField - internalGetStartDeadlines() { - if (startDeadlines_ == null) { - return com.google.protobuf.MapField.emptyMapField( - StartDeadlinesDefaultEntryHolder.defaultEntry); + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, taskName_); } - return startDeadlines_; - } - - public int getStartDeadlinesCount() { - return internalGetStartDeadlines().getMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public boolean containsStartDeadlines( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, taskDescription_); } - return internalGetStartDeadlines().getMap().containsKey(key); - } - - /** - * Use {@link #getStartDeadlinesMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getStartDeadlines() { - return getStartDeadlinesMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public java.util.Map getStartDeadlinesMap() { - return internalGetStartDeadlines().getMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getStartDeadlinesOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetStartDeadlines().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getStartDeadlinesOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, taskPriority_); } - java.util.Map map = - internalGetStartDeadlines().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); + if (((bitField0_ & 0x00000008) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, actualOwner_); } - return map.get(key); - } - - public static final int COMPLETED_DEADLINES_FIELD_NUMBER = 14; - - private static final class CompletedDeadlinesDefaultEntryHolder { - static final com.google.protobuf.MapEntry defaultEntry = - com.google.protobuf.MapEntry. newDefaultInstance( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_CompletedDeadlinesEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.MESSAGE, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.getDefaultInstance()); - } - - @SuppressWarnings("serial") - private com.google.protobuf.MapField completedDeadlines_; - - private com.google.protobuf.MapField - internalGetCompletedDeadlines() { - if (completedDeadlines_ == null) { - return com.google.protobuf.MapField.emptyMapField( - CompletedDeadlinesDefaultEntryHolder.defaultEntry); + for (int i = 0; i < potUsers_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, potUsers_.getRaw(i)); } - return completedDeadlines_; - } - - public int getCompletedDeadlinesCount() { - return internalGetCompletedDeadlines().getMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public boolean containsCompletedDeadlines( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); + for (int i = 0; i < potGroups_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, potGroups_.getRaw(i)); } - return internalGetCompletedDeadlines().getMap().containsKey(key); - } - - /** - * Use {@link #getCompletedDeadlinesMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getCompletedDeadlines() { - return getCompletedDeadlinesMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public java.util.Map getCompletedDeadlinesMap() { - return internalGetCompletedDeadlines().getMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getCompletedDeadlinesOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetCompletedDeadlines().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getCompletedDeadlinesOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); + for (int i = 0; i < excludedUsers_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 7, excludedUsers_.getRaw(i)); + } + for (int i = 0; i < adminUsers_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 8, adminUsers_.getRaw(i)); } - java.util.Map map = - internalGetCompletedDeadlines().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); + for (int i = 0; i < adminGroups_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 9, adminGroups_.getRaw(i)); + } + if (((bitField0_ & 0x00000010) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 10, taskReferenceName_); } - return map.get(key); - } - - public static final int START_REASSIGMENTS_FIELD_NUMBER = 15; - - private static final class StartReassigmentsDefaultEntryHolder { - static final com.google.protobuf.MapEntry defaultEntry = - com.google.protobuf.MapEntry. newDefaultInstance( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_StartReassigmentsEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.MESSAGE, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.getDefaultInstance()); - } - - @SuppressWarnings("serial") - private com.google.protobuf.MapField startReassigments_; - - private com.google.protobuf.MapField - internalGetStartReassigments() { - if (startReassigments_ == null) { - return com.google.protobuf.MapField.emptyMapField( - StartReassigmentsDefaultEntryHolder.defaultEntry); - } - return startReassigments_; - } - - public int getStartReassigmentsCount() { - return internalGetStartReassigments().getMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public boolean containsStartReassigments( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetStartReassigments().getMap().containsKey(key); - } - - /** - * Use {@link #getStartReassigmentsMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getStartReassigments() { - return getStartReassigmentsMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public java.util.Map getStartReassigmentsMap() { - return internalGetStartReassigments().getMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getStartReassigmentsOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetStartReassigments().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getStartReassigmentsOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetStartReassigments().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return map.get(key); - } - - public static final int COMPLETED_REASSIGMENTS_FIELD_NUMBER = 16; - - private static final class CompletedReassigmentsDefaultEntryHolder { - static final com.google.protobuf.MapEntry defaultEntry = - com.google.protobuf.MapEntry. newDefaultInstance( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_CompletedReassigmentsEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.MESSAGE, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.getDefaultInstance()); - } - - @SuppressWarnings("serial") - private com.google.protobuf.MapField completedReassigments_; - - private com.google.protobuf.MapField - internalGetCompletedReassigments() { - if (completedReassigments_ == null) { - return com.google.protobuf.MapField.emptyMapField( - CompletedReassigmentsDefaultEntryHolder.defaultEntry); - } - return completedReassigments_; - } - - public int getCompletedReassigmentsCount() { - return internalGetCompletedReassigments().getMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public boolean containsCompletedReassigments( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetCompletedReassigments().getMap().containsKey(key); - } - - /** - * Use {@link #getCompletedReassigmentsMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getCompletedReassigments() { - return getCompletedReassigmentsMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public java.util.Map getCompletedReassigmentsMap() { - return internalGetCompletedReassigments().getMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getCompletedReassigmentsOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetCompletedReassigments().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getCompletedReassigmentsOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetCompletedReassigments().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return map.get(key); - } - - private byte memoizedIsInitialized = -1; - - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) - return true; - if (isInitialized == 0) - return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, taskName_); - } - if (((bitField0_ & 0x00000002) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, taskDescription_); - } - if (((bitField0_ & 0x00000004) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 3, taskPriority_); - } - if (((bitField0_ & 0x00000008) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 4, actualOwner_); - } - for (int i = 0; i < potUsers_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 5, potUsers_.getRaw(i)); - } - for (int i = 0; i < potGroups_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 6, potGroups_.getRaw(i)); - } - for (int i = 0; i < excludedUsers_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 7, excludedUsers_.getRaw(i)); - } - for (int i = 0; i < adminUsers_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 8, adminUsers_.getRaw(i)); - } - for (int i = 0; i < adminGroups_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 9, adminGroups_.getRaw(i)); - } - if (((bitField0_ & 0x00000010) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 10, taskReferenceName_); - } - for (int i = 0; i < comments_.size(); i++) { - output.writeMessage(11, comments_.get(i)); - } - for (int i = 0; i < attachments_.size(); i++) { - output.writeMessage(12, attachments_.get(i)); - } - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetStartDeadlines(), - StartDeadlinesDefaultEntryHolder.defaultEntry, - 13); - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetCompletedDeadlines(), - CompletedDeadlinesDefaultEntryHolder.defaultEntry, - 14); - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetStartReassigments(), - StartReassigmentsDefaultEntryHolder.defaultEntry, - 15); - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetCompletedReassigments(), - CompletedReassigmentsDefaultEntryHolder.defaultEntry, - 16); - getUnknownFields().writeTo(output); + getUnknownFields().writeTo(output); } @java.lang.Override @@ -1686,50 +967,6 @@ public int getSerializedSize() { if (((bitField0_ & 0x00000010) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(10, taskReferenceName_); } - for (int i = 0; i < comments_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(11, comments_.get(i)); - } - for (int i = 0; i < attachments_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(12, attachments_.get(i)); - } - for (java.util.Map.Entry entry : internalGetStartDeadlines().getMap().entrySet()) { - com.google.protobuf.MapEntry startDeadlines__ = - StartDeadlinesDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(13, startDeadlines__); - } - for (java.util.Map.Entry entry : internalGetCompletedDeadlines().getMap().entrySet()) { - com.google.protobuf.MapEntry completedDeadlines__ = - CompletedDeadlinesDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(14, completedDeadlines__); - } - for (java.util.Map.Entry entry : internalGetStartReassigments().getMap().entrySet()) { - com.google.protobuf.MapEntry startReassigments__ = - StartReassigmentsDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(15, startReassigments__); - } - for (java.util.Map.Entry entry : internalGetCompletedReassigments().getMap().entrySet()) { - com.google.protobuf.MapEntry completedReassigments__ = - CompletedReassigmentsDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(16, completedReassigments__); - } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1795,24 +1032,6 @@ public boolean equals(final java.lang.Object obj) { .equals(other.getTaskReferenceName())) return false; } - if (!getCommentsList() - .equals(other.getCommentsList())) - return false; - if (!getAttachmentsList() - .equals(other.getAttachmentsList())) - return false; - if (!internalGetStartDeadlines().equals( - other.internalGetStartDeadlines())) - return false; - if (!internalGetCompletedDeadlines().equals( - other.internalGetCompletedDeadlines())) - return false; - if (!internalGetStartReassigments().equals( - other.internalGetStartReassigments())) - return false; - if (!internalGetCompletedReassigments().equals( - other.internalGetCompletedReassigments())) - return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; @@ -1865,30 +1084,6 @@ public int hashCode() { hash = (37 * hash) + TASK_REFERENCE_NAME_FIELD_NUMBER; hash = (53 * hash) + getTaskReferenceName().hashCode(); } - if (getCommentsCount() > 0) { - hash = (37 * hash) + COMMENTS_FIELD_NUMBER; - hash = (53 * hash) + getCommentsList().hashCode(); - } - if (getAttachmentsCount() > 0) { - hash = (37 * hash) + ATTACHMENTS_FIELD_NUMBER; - hash = (53 * hash) + getAttachmentsList().hashCode(); - } - if (!internalGetStartDeadlines().getMap().isEmpty()) { - hash = (37 * hash) + START_DEADLINES_FIELD_NUMBER; - hash = (53 * hash) + internalGetStartDeadlines().hashCode(); - } - if (!internalGetCompletedDeadlines().getMap().isEmpty()) { - hash = (37 * hash) + COMPLETED_DEADLINES_FIELD_NUMBER; - hash = (53 * hash) + internalGetCompletedDeadlines().hashCode(); - } - if (!internalGetStartReassigments().getMap().isEmpty()) { - hash = (37 * hash) + START_REASSIGMENTS_FIELD_NUMBER; - hash = (53 * hash) + internalGetStartReassigments().hashCode(); - } - if (!internalGetCompletedReassigments().getMap().isEmpty()) { - hash = (37 * hash) + COMPLETED_REASSIGMENTS_FIELD_NUMBER; - hash = (53 * hash) + internalGetCompletedReassigments().hashCode(); - } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -2014,42 +1209,6 @@ public static final class Builder extends return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_descriptor; } - @SuppressWarnings({ "rawtypes" }) - protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( - int number) { - switch (number) { - case 13: - return internalGetStartDeadlines(); - case 14: - return internalGetCompletedDeadlines(); - case 15: - return internalGetStartReassigments(); - case 16: - return internalGetCompletedReassigments(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - - @SuppressWarnings({ "rawtypes" }) - protected com.google.protobuf.MapFieldReflectionAccessor internalGetMutableMapFieldReflection( - int number) { - switch (number) { - case 13: - return internalGetMutableStartDeadlines(); - case 14: - return internalGetMutableCompletedDeadlines(); - case 15: - return internalGetMutableStartReassigments(); - case 16: - return internalGetMutableCompletedReassigments(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { @@ -2089,24 +1248,6 @@ public Builder clear() { adminGroups_ = com.google.protobuf.LazyStringArrayList.emptyList(); taskReferenceName_ = ""; - if (commentsBuilder_ == null) { - comments_ = java.util.Collections.emptyList(); - } else { - comments_ = null; - commentsBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000400); - if (attachmentsBuilder_ == null) { - attachments_ = java.util.Collections.emptyList(); - } else { - attachments_ = null; - attachmentsBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000800); - internalGetMutableStartDeadlines().clear(); - internalGetMutableCompletedDeadlines().clear(); - internalGetMutableStartReassigments().clear(); - internalGetMutableCompletedReassigments().clear(); return this; } @@ -2134,7 +1275,6 @@ public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWor public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData buildPartial() { org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData result = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData(this); - buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } @@ -2142,27 +1282,6 @@ public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWor return result; } - private void buildPartialRepeatedFields(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData result) { - if (commentsBuilder_ == null) { - if (((bitField0_ & 0x00000400) != 0)) { - comments_ = java.util.Collections.unmodifiableList(comments_); - bitField0_ = (bitField0_ & ~0x00000400); - } - result.comments_ = comments_; - } else { - result.comments_ = commentsBuilder_.build(); - } - if (attachmentsBuilder_ == null) { - if (((bitField0_ & 0x00000800) != 0)) { - attachments_ = java.util.Collections.unmodifiableList(attachments_); - bitField0_ = (bitField0_ & ~0x00000800); - } - result.attachments_ = attachments_; - } else { - result.attachments_ = attachmentsBuilder_.build(); - } - } - private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; @@ -2206,18 +1325,6 @@ private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsP result.taskReferenceName_ = taskReferenceName_; to_bitField0_ |= 0x00000010; } - if (((from_bitField0_ & 0x00001000) != 0)) { - result.startDeadlines_ = internalGetStartDeadlines().build(StartDeadlinesDefaultEntryHolder.defaultEntry); - } - if (((from_bitField0_ & 0x00002000) != 0)) { - result.completedDeadlines_ = internalGetCompletedDeadlines().build(CompletedDeadlinesDefaultEntryHolder.defaultEntry); - } - if (((from_bitField0_ & 0x00004000) != 0)) { - result.startReassigments_ = internalGetStartReassigments().build(StartReassigmentsDefaultEntryHolder.defaultEntry); - } - if (((from_bitField0_ & 0x00008000) != 0)) { - result.completedReassigments_ = internalGetCompletedReassigments().build(CompletedReassigmentsDefaultEntryHolder.defaultEntry); - } result.bitField0_ |= to_bitField0_; } @@ -2347,68 +1454,6 @@ public Builder mergeFrom(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsPro bitField0_ |= 0x00000200; onChanged(); } - if (commentsBuilder_ == null) { - if (!other.comments_.isEmpty()) { - if (comments_.isEmpty()) { - comments_ = other.comments_; - bitField0_ = (bitField0_ & ~0x00000400); - } else { - ensureCommentsIsMutable(); - comments_.addAll(other.comments_); - } - onChanged(); - } - } else { - if (!other.comments_.isEmpty()) { - if (commentsBuilder_.isEmpty()) { - commentsBuilder_.dispose(); - commentsBuilder_ = null; - comments_ = other.comments_; - bitField0_ = (bitField0_ & ~0x00000400); - commentsBuilder_ = - com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? getCommentsFieldBuilder() : null; - } else { - commentsBuilder_.addAllMessages(other.comments_); - } - } - } - if (attachmentsBuilder_ == null) { - if (!other.attachments_.isEmpty()) { - if (attachments_.isEmpty()) { - attachments_ = other.attachments_; - bitField0_ = (bitField0_ & ~0x00000800); - } else { - ensureAttachmentsIsMutable(); - attachments_.addAll(other.attachments_); - } - onChanged(); - } - } else { - if (!other.attachments_.isEmpty()) { - if (attachmentsBuilder_.isEmpty()) { - attachmentsBuilder_.dispose(); - attachmentsBuilder_ = null; - attachments_ = other.attachments_; - bitField0_ = (bitField0_ & ~0x00000800); - attachmentsBuilder_ = - com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? getAttachmentsFieldBuilder() : null; - } else { - attachmentsBuilder_.addAllMessages(other.attachments_); - } - } - } - internalGetMutableStartDeadlines().mergeFrom( - other.internalGetStartDeadlines()); - bitField0_ |= 0x00001000; - internalGetMutableCompletedDeadlines().mergeFrom( - other.internalGetCompletedDeadlines()); - bitField0_ |= 0x00002000; - internalGetMutableStartReassigments().mergeFrom( - other.internalGetStartReassigments()); - bitField0_ |= 0x00004000; - internalGetMutableCompletedReassigments().mergeFrom( - other.internalGetCompletedReassigments()); - bitField0_ |= 0x00008000; this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -2490,64 +1535,6 @@ public Builder mergeFrom( bitField0_ |= 0x00000200; break; } // case 82 - case 90: { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment m = - input.readMessage( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.parser(), - extensionRegistry); - if (commentsBuilder_ == null) { - ensureCommentsIsMutable(); - comments_.add(m); - } else { - commentsBuilder_.addMessage(m); - } - break; - } // case 90 - case 98: { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment m = - input.readMessage( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.parser(), - extensionRegistry); - if (attachmentsBuilder_ == null) { - ensureAttachmentsIsMutable(); - attachments_.add(m); - } else { - attachmentsBuilder_.addMessage(m); - } - break; - } // case 98 - case 106: { - com.google.protobuf.MapEntry startDeadlines__ = input.readMessage( - StartDeadlinesDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - internalGetMutableStartDeadlines().ensureBuilderMap().put( - startDeadlines__.getKey(), startDeadlines__.getValue()); - bitField0_ |= 0x00001000; - break; - } // case 106 - case 114: { - com.google.protobuf.MapEntry completedDeadlines__ = input.readMessage( - CompletedDeadlinesDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - internalGetMutableCompletedDeadlines().ensureBuilderMap().put( - completedDeadlines__.getKey(), completedDeadlines__.getValue()); - bitField0_ |= 0x00002000; - break; - } // case 114 - case 122: { - com.google.protobuf.MapEntry startReassigments__ = input.readMessage( - StartReassigmentsDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - internalGetMutableStartReassigments().ensureBuilderMap().put( - startReassigments__.getKey(), startReassigments__.getValue()); - bitField0_ |= 0x00004000; - break; - } // case 122 - case 130: { - com.google.protobuf.MapEntry completedReassigments__ = input.readMessage( - CompletedReassigmentsDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - internalGetMutableCompletedReassigments().ensureBuilderMap().put( - completedReassigments__.getKey(), completedReassigments__.getValue()); - bitField0_ |= 0x00008000; - break; - } // case 130 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -3726,5530 +2713,63 @@ public Builder setTaskReferenceNameBytes( return this; } - private java.util.List comments_ = - java.util.Collections.emptyList(); - - private void ensureCommentsIsMutable() { - if (!((bitField0_ & 0x00000400) != 0)) { - comments_ = new java.util.ArrayList(comments_); - bitField0_ |= 0x00000400; - } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); } - private com.google.protobuf.RepeatedFieldBuilderV3 commentsBuilder_; - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public java.util.List getCommentsList() { - if (commentsBuilder_ == null) { - return java.util.Collections.unmodifiableList(comments_); - } else { - return commentsBuilder_.getMessageList(); - } + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); } - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public int getCommentsCount() { - if (commentsBuilder_ == null) { - return comments_.size(); - } else { - return commentsBuilder_.getCount(); - } - } + // @@protoc_insertion_point(builder_scope:org.jbpm.flow.serialization.protobuf.HumanTaskWorkItemData) + } - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment getComments(int index) { - if (commentsBuilder_ == null) { - return comments_.get(index); - } else { - return commentsBuilder_.getMessage(index); - } - } + // @@protoc_insertion_point(class_scope:org.jbpm.flow.serialization.protobuf.HumanTaskWorkItemData) + private static final org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData(); + } - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder setComments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment value) { - if (commentsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureCommentsIsMutable(); - comments_.set(index, value); - onChanged(); - } else { - commentsBuilder_.setMessage(index, value); - } - return this; - } + public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData getDefaultInstance() { + return DEFAULT_INSTANCE; + } - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder setComments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder builderForValue) { - if (commentsBuilder_ == null) { - ensureCommentsIsMutable(); - comments_.set(index, builderForValue.build()); - onChanged(); - } else { - commentsBuilder_.setMessage(index, builderForValue.build()); + private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public HumanTaskWorkItemData parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); } - return this; + return builder.buildPartial(); } + }; - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder addComments(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment value) { - if (commentsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureCommentsIsMutable(); - comments_.add(value); - onChanged(); - } else { - commentsBuilder_.addMessage(value); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder addComments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment value) { - if (commentsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureCommentsIsMutable(); - comments_.add(index, value); - onChanged(); - } else { - commentsBuilder_.addMessage(index, value); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder addComments( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder builderForValue) { - if (commentsBuilder_ == null) { - ensureCommentsIsMutable(); - comments_.add(builderForValue.build()); - onChanged(); - } else { - commentsBuilder_.addMessage(builderForValue.build()); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder addComments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder builderForValue) { - if (commentsBuilder_ == null) { - ensureCommentsIsMutable(); - comments_.add(index, builderForValue.build()); - onChanged(); - } else { - commentsBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder addAllComments( - java.lang.Iterable values) { - if (commentsBuilder_ == null) { - ensureCommentsIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, comments_); - onChanged(); - } else { - commentsBuilder_.addAllMessages(values); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder clearComments() { - if (commentsBuilder_ == null) { - comments_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000400); - onChanged(); - } else { - commentsBuilder_.clear(); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public Builder removeComments(int index) { - if (commentsBuilder_ == null) { - ensureCommentsIsMutable(); - comments_.remove(index); - onChanged(); - } else { - commentsBuilder_.remove(index); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder getCommentsBuilder( - int index) { - return getCommentsFieldBuilder().getBuilder(index); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.CommentOrBuilder getCommentsOrBuilder( - int index) { - if (commentsBuilder_ == null) { - return comments_.get(index); - } else { - return commentsBuilder_.getMessageOrBuilder(index); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public java.util.List - getCommentsOrBuilderList() { - if (commentsBuilder_ != null) { - return commentsBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(comments_); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder addCommentsBuilder() { - return getCommentsFieldBuilder().addBuilder( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.getDefaultInstance()); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder addCommentsBuilder( - int index) { - return getCommentsFieldBuilder().addBuilder( - index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.getDefaultInstance()); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Comment comments = 11; - */ - public java.util.List - getCommentsBuilderList() { - return getCommentsFieldBuilder().getBuilderList(); - } - - private com.google.protobuf.RepeatedFieldBuilderV3 - getCommentsFieldBuilder() { - if (commentsBuilder_ == null) { - commentsBuilder_ = - new com.google.protobuf.RepeatedFieldBuilderV3( - comments_, - ((bitField0_ & 0x00000400) != 0), - getParentForChildren(), - isClean()); - comments_ = null; - } - return commentsBuilder_; - } - - private java.util.List attachments_ = - java.util.Collections.emptyList(); - - private void ensureAttachmentsIsMutable() { - if (!((bitField0_ & 0x00000800) != 0)) { - attachments_ = new java.util.ArrayList(attachments_); - bitField0_ |= 0x00000800; - } - } - - private com.google.protobuf.RepeatedFieldBuilderV3 attachmentsBuilder_; - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public java.util.List getAttachmentsList() { - if (attachmentsBuilder_ == null) { - return java.util.Collections.unmodifiableList(attachments_); - } else { - return attachmentsBuilder_.getMessageList(); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public int getAttachmentsCount() { - if (attachmentsBuilder_ == null) { - return attachments_.size(); - } else { - return attachmentsBuilder_.getCount(); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment getAttachments(int index) { - if (attachmentsBuilder_ == null) { - return attachments_.get(index); - } else { - return attachmentsBuilder_.getMessage(index); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder setAttachments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment value) { - if (attachmentsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureAttachmentsIsMutable(); - attachments_.set(index, value); - onChanged(); - } else { - attachmentsBuilder_.setMessage(index, value); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder setAttachments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder builderForValue) { - if (attachmentsBuilder_ == null) { - ensureAttachmentsIsMutable(); - attachments_.set(index, builderForValue.build()); - onChanged(); - } else { - attachmentsBuilder_.setMessage(index, builderForValue.build()); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder addAttachments(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment value) { - if (attachmentsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureAttachmentsIsMutable(); - attachments_.add(value); - onChanged(); - } else { - attachmentsBuilder_.addMessage(value); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder addAttachments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment value) { - if (attachmentsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureAttachmentsIsMutable(); - attachments_.add(index, value); - onChanged(); - } else { - attachmentsBuilder_.addMessage(index, value); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder addAttachments( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder builderForValue) { - if (attachmentsBuilder_ == null) { - ensureAttachmentsIsMutable(); - attachments_.add(builderForValue.build()); - onChanged(); - } else { - attachmentsBuilder_.addMessage(builderForValue.build()); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder addAttachments( - int index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder builderForValue) { - if (attachmentsBuilder_ == null) { - ensureAttachmentsIsMutable(); - attachments_.add(index, builderForValue.build()); - onChanged(); - } else { - attachmentsBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder addAllAttachments( - java.lang.Iterable values) { - if (attachmentsBuilder_ == null) { - ensureAttachmentsIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, attachments_); - onChanged(); - } else { - attachmentsBuilder_.addAllMessages(values); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder clearAttachments() { - if (attachmentsBuilder_ == null) { - attachments_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000800); - onChanged(); - } else { - attachmentsBuilder_.clear(); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public Builder removeAttachments(int index) { - if (attachmentsBuilder_ == null) { - ensureAttachmentsIsMutable(); - attachments_.remove(index); - onChanged(); - } else { - attachmentsBuilder_.remove(index); - } - return this; - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder getAttachmentsBuilder( - int index) { - return getAttachmentsFieldBuilder().getBuilder(index); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.AttachmentOrBuilder getAttachmentsOrBuilder( - int index) { - if (attachmentsBuilder_ == null) { - return attachments_.get(index); - } else { - return attachmentsBuilder_.getMessageOrBuilder(index); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public java.util.List - getAttachmentsOrBuilderList() { - if (attachmentsBuilder_ != null) { - return attachmentsBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(attachments_); - } - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder addAttachmentsBuilder() { - return getAttachmentsFieldBuilder().addBuilder( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.getDefaultInstance()); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder addAttachmentsBuilder( - int index) { - return getAttachmentsFieldBuilder().addBuilder( - index, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.getDefaultInstance()); - } - - /** - * repeated .org.jbpm.flow.serialization.protobuf.Attachment attachments = 12; - */ - public java.util.List - getAttachmentsBuilderList() { - return getAttachmentsFieldBuilder().getBuilderList(); - } - - private com.google.protobuf.RepeatedFieldBuilderV3 - getAttachmentsFieldBuilder() { - if (attachmentsBuilder_ == null) { - attachmentsBuilder_ = - new com.google.protobuf.RepeatedFieldBuilderV3( - attachments_, - ((bitField0_ & 0x00000800) != 0), - getParentForChildren(), - isClean()); - attachments_ = null; - } - return attachmentsBuilder_; - } - - private static final class StartDeadlinesConverter implements - com.google.protobuf.MapFieldBuilder.Converter { - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline build(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.DeadlineOrBuilder val) { - if (val instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) { - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) val; - } - return ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder) val).build(); - } - - @java.lang.Override - public com.google.protobuf.MapEntry defaultEntry() { - return StartDeadlinesDefaultEntryHolder.defaultEntry; - } - }; - - private static final StartDeadlinesConverter startDeadlinesConverter = new StartDeadlinesConverter(); - - private com.google.protobuf.MapFieldBuilder startDeadlines_; - - private com.google.protobuf.MapFieldBuilder - internalGetStartDeadlines() { - if (startDeadlines_ == null) { - return new com.google.protobuf.MapFieldBuilder<>(startDeadlinesConverter); - } - return startDeadlines_; - } - - private com.google.protobuf.MapFieldBuilder - internalGetMutableStartDeadlines() { - if (startDeadlines_ == null) { - startDeadlines_ = new com.google.protobuf.MapFieldBuilder<>(startDeadlinesConverter); - } - bitField0_ |= 0x00001000; - onChanged(); - return startDeadlines_; - } - - public int getStartDeadlinesCount() { - return internalGetStartDeadlines().ensureBuilderMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public boolean containsStartDeadlines( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetStartDeadlines().ensureBuilderMap().containsKey(key); - } - - /** - * Use {@link #getStartDeadlinesMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getStartDeadlines() { - return getStartDeadlinesMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public java.util.Map getStartDeadlinesMap() { - return internalGetStartDeadlines().getImmutableMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getStartDeadlinesOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableStartDeadlines().ensureBuilderMap(); - return map.containsKey(key) ? startDeadlinesConverter.build(map.get(key)) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getStartDeadlinesOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableStartDeadlines().ensureBuilderMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return startDeadlinesConverter.build(map.get(key)); - } - - public Builder clearStartDeadlines() { - bitField0_ = (bitField0_ & ~0x00001000); - internalGetMutableStartDeadlines().clear(); - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - public Builder removeStartDeadlines( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - internalGetMutableStartDeadlines().ensureBuilderMap() - .remove(key); - return this; - } - - /** - * Use alternate mutation accessors instead. - */ - @java.lang.Deprecated - public java.util.Map - getMutableStartDeadlines() { - bitField0_ |= 0x00001000; - return internalGetMutableStartDeadlines().ensureMessageMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - public Builder putStartDeadlines( - java.lang.String key, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline value) { - if (key == null) { - throw new NullPointerException("map key"); - } - if (value == null) { - throw new NullPointerException("map value"); - } - internalGetMutableStartDeadlines().ensureBuilderMap() - .put(key, value); - bitField0_ |= 0x00001000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - public Builder putAllStartDeadlines( - java.util.Map values) { - for (java.util.Map.Entry e : values.entrySet()) { - if (e.getKey() == null || e.getValue() == null) { - throw new NullPointerException(); - } - } - internalGetMutableStartDeadlines().ensureBuilderMap() - .putAll(values); - bitField0_ |= 0x00001000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> start_deadlines = 13; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder putStartDeadlinesBuilderIfAbsent( - java.lang.String key) { - java.util.Map builderMap = internalGetMutableStartDeadlines().ensureBuilderMap(); - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.DeadlineOrBuilder entry = builderMap.get(key); - if (entry == null) { - entry = org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.newBuilder(); - builderMap.put(key, entry); - } - if (entry instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) { - entry = ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) entry).toBuilder(); - builderMap.put(key, entry); - } - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder) entry; - } - - private static final class CompletedDeadlinesConverter implements - com.google.protobuf.MapFieldBuilder.Converter { - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline build(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.DeadlineOrBuilder val) { - if (val instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) { - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) val; - } - return ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder) val).build(); - } - - @java.lang.Override - public com.google.protobuf.MapEntry defaultEntry() { - return CompletedDeadlinesDefaultEntryHolder.defaultEntry; - } - }; - - private static final CompletedDeadlinesConverter completedDeadlinesConverter = new CompletedDeadlinesConverter(); - - private com.google.protobuf.MapFieldBuilder completedDeadlines_; - - private com.google.protobuf.MapFieldBuilder - internalGetCompletedDeadlines() { - if (completedDeadlines_ == null) { - return new com.google.protobuf.MapFieldBuilder<>(completedDeadlinesConverter); - } - return completedDeadlines_; - } - - private com.google.protobuf.MapFieldBuilder - internalGetMutableCompletedDeadlines() { - if (completedDeadlines_ == null) { - completedDeadlines_ = new com.google.protobuf.MapFieldBuilder<>(completedDeadlinesConverter); - } - bitField0_ |= 0x00002000; - onChanged(); - return completedDeadlines_; - } - - public int getCompletedDeadlinesCount() { - return internalGetCompletedDeadlines().ensureBuilderMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public boolean containsCompletedDeadlines( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetCompletedDeadlines().ensureBuilderMap().containsKey(key); - } - - /** - * Use {@link #getCompletedDeadlinesMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getCompletedDeadlines() { - return getCompletedDeadlinesMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public java.util.Map getCompletedDeadlinesMap() { - return internalGetCompletedDeadlines().getImmutableMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getCompletedDeadlinesOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableCompletedDeadlines().ensureBuilderMap(); - return map.containsKey(key) ? completedDeadlinesConverter.build(map.get(key)) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getCompletedDeadlinesOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableCompletedDeadlines().ensureBuilderMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return completedDeadlinesConverter.build(map.get(key)); - } - - public Builder clearCompletedDeadlines() { - bitField0_ = (bitField0_ & ~0x00002000); - internalGetMutableCompletedDeadlines().clear(); - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - public Builder removeCompletedDeadlines( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - internalGetMutableCompletedDeadlines().ensureBuilderMap() - .remove(key); - return this; - } - - /** - * Use alternate mutation accessors instead. - */ - @java.lang.Deprecated - public java.util.Map - getMutableCompletedDeadlines() { - bitField0_ |= 0x00002000; - return internalGetMutableCompletedDeadlines().ensureMessageMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - public Builder putCompletedDeadlines( - java.lang.String key, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline value) { - if (key == null) { - throw new NullPointerException("map key"); - } - if (value == null) { - throw new NullPointerException("map value"); - } - internalGetMutableCompletedDeadlines().ensureBuilderMap() - .put(key, value); - bitField0_ |= 0x00002000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - public Builder putAllCompletedDeadlines( - java.util.Map values) { - for (java.util.Map.Entry e : values.entrySet()) { - if (e.getKey() == null || e.getValue() == null) { - throw new NullPointerException(); - } - } - internalGetMutableCompletedDeadlines().ensureBuilderMap() - .putAll(values); - bitField0_ |= 0x00002000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Deadline> completed_deadlines = 14; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder putCompletedDeadlinesBuilderIfAbsent( - java.lang.String key) { - java.util.Map builderMap = internalGetMutableCompletedDeadlines().ensureBuilderMap(); - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.DeadlineOrBuilder entry = builderMap.get(key); - if (entry == null) { - entry = org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.newBuilder(); - builderMap.put(key, entry); - } - if (entry instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) { - entry = ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) entry).toBuilder(); - builderMap.put(key, entry); - } - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder) entry; - } - - private static final class StartReassigmentsConverter implements - com.google.protobuf.MapFieldBuilder.Converter { - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment build(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.ReassignmentOrBuilder val) { - if (val instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) { - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) val; - } - return ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder) val).build(); - } - - @java.lang.Override - public com.google.protobuf.MapEntry defaultEntry() { - return StartReassigmentsDefaultEntryHolder.defaultEntry; - } - }; - - private static final StartReassigmentsConverter startReassigmentsConverter = new StartReassigmentsConverter(); - - private com.google.protobuf.MapFieldBuilder startReassigments_; - - private com.google.protobuf.MapFieldBuilder - internalGetStartReassigments() { - if (startReassigments_ == null) { - return new com.google.protobuf.MapFieldBuilder<>(startReassigmentsConverter); - } - return startReassigments_; - } - - private com.google.protobuf.MapFieldBuilder - internalGetMutableStartReassigments() { - if (startReassigments_ == null) { - startReassigments_ = new com.google.protobuf.MapFieldBuilder<>(startReassigmentsConverter); - } - bitField0_ |= 0x00004000; - onChanged(); - return startReassigments_; - } - - public int getStartReassigmentsCount() { - return internalGetStartReassigments().ensureBuilderMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public boolean containsStartReassigments( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetStartReassigments().ensureBuilderMap().containsKey(key); - } - - /** - * Use {@link #getStartReassigmentsMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getStartReassigments() { - return getStartReassigmentsMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public java.util.Map getStartReassigmentsMap() { - return internalGetStartReassigments().getImmutableMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getStartReassigmentsOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableStartReassigments().ensureBuilderMap(); - return map.containsKey(key) ? startReassigmentsConverter.build(map.get(key)) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getStartReassigmentsOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableStartReassigments().ensureBuilderMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return startReassigmentsConverter.build(map.get(key)); - } - - public Builder clearStartReassigments() { - bitField0_ = (bitField0_ & ~0x00004000); - internalGetMutableStartReassigments().clear(); - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - public Builder removeStartReassigments( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - internalGetMutableStartReassigments().ensureBuilderMap() - .remove(key); - return this; - } - - /** - * Use alternate mutation accessors instead. - */ - @java.lang.Deprecated - public java.util.Map - getMutableStartReassigments() { - bitField0_ |= 0x00004000; - return internalGetMutableStartReassigments().ensureMessageMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - public Builder putStartReassigments( - java.lang.String key, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment value) { - if (key == null) { - throw new NullPointerException("map key"); - } - if (value == null) { - throw new NullPointerException("map value"); - } - internalGetMutableStartReassigments().ensureBuilderMap() - .put(key, value); - bitField0_ |= 0x00004000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - public Builder putAllStartReassigments( - java.util.Map values) { - for (java.util.Map.Entry e : values.entrySet()) { - if (e.getKey() == null || e.getValue() == null) { - throw new NullPointerException(); - } - } - internalGetMutableStartReassigments().ensureBuilderMap() - .putAll(values); - bitField0_ |= 0x00004000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> start_reassigments = 15; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder putStartReassigmentsBuilderIfAbsent( - java.lang.String key) { - java.util.Map builderMap = - internalGetMutableStartReassigments().ensureBuilderMap(); - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.ReassignmentOrBuilder entry = builderMap.get(key); - if (entry == null) { - entry = org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.newBuilder(); - builderMap.put(key, entry); - } - if (entry instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) { - entry = ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) entry).toBuilder(); - builderMap.put(key, entry); - } - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder) entry; - } - - private static final class CompletedReassigmentsConverter implements - com.google.protobuf.MapFieldBuilder.Converter { - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment build(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.ReassignmentOrBuilder val) { - if (val instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) { - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) val; - } - return ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder) val).build(); - } - - @java.lang.Override - public com.google.protobuf.MapEntry defaultEntry() { - return CompletedReassigmentsDefaultEntryHolder.defaultEntry; - } - }; - - private static final CompletedReassigmentsConverter completedReassigmentsConverter = new CompletedReassigmentsConverter(); - - private com.google.protobuf.MapFieldBuilder completedReassigments_; - - private com.google.protobuf.MapFieldBuilder - internalGetCompletedReassigments() { - if (completedReassigments_ == null) { - return new com.google.protobuf.MapFieldBuilder<>(completedReassigmentsConverter); - } - return completedReassigments_; - } - - private com.google.protobuf.MapFieldBuilder - internalGetMutableCompletedReassigments() { - if (completedReassigments_ == null) { - completedReassigments_ = new com.google.protobuf.MapFieldBuilder<>(completedReassigmentsConverter); - } - bitField0_ |= 0x00008000; - onChanged(); - return completedReassigments_; - } - - public int getCompletedReassigmentsCount() { - return internalGetCompletedReassigments().ensureBuilderMap().size(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public boolean containsCompletedReassigments( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetCompletedReassigments().ensureBuilderMap().containsKey(key); - } - - /** - * Use {@link #getCompletedReassigmentsMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getCompletedReassigments() { - return getCompletedReassigmentsMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public java.util.Map getCompletedReassigmentsMap() { - return internalGetCompletedReassigments().getImmutableMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getCompletedReassigmentsOrDefault( - java.lang.String key, - /* nullable */ - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableCompletedReassigments().ensureBuilderMap(); - return map.containsKey(key) ? completedReassigmentsConverter.build(map.get(key)) : defaultValue; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getCompletedReassigmentsOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = internalGetMutableCompletedReassigments().ensureBuilderMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return completedReassigmentsConverter.build(map.get(key)); - } - - public Builder clearCompletedReassigments() { - bitField0_ = (bitField0_ & ~0x00008000); - internalGetMutableCompletedReassigments().clear(); - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - public Builder removeCompletedReassigments( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - internalGetMutableCompletedReassigments().ensureBuilderMap() - .remove(key); - return this; - } - - /** - * Use alternate mutation accessors instead. - */ - @java.lang.Deprecated - public java.util.Map - getMutableCompletedReassigments() { - bitField0_ |= 0x00008000; - return internalGetMutableCompletedReassigments().ensureMessageMap(); - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - public Builder putCompletedReassigments( - java.lang.String key, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment value) { - if (key == null) { - throw new NullPointerException("map key"); - } - if (value == null) { - throw new NullPointerException("map value"); - } - internalGetMutableCompletedReassigments().ensureBuilderMap() - .put(key, value); - bitField0_ |= 0x00008000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - public Builder putAllCompletedReassigments( - java.util.Map values) { - for (java.util.Map.Entry e : values.entrySet()) { - if (e.getKey() == null || e.getValue() == null) { - throw new NullPointerException(); - } - } - internalGetMutableCompletedReassigments().ensureBuilderMap() - .putAll(values); - bitField0_ |= 0x00008000; - return this; - } - - /** - * map<string, .org.jbpm.flow.serialization.protobuf.Reassignment> completed_reassigments = 16; - */ - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder putCompletedReassigmentsBuilderIfAbsent( - java.lang.String key) { - java.util.Map builderMap = - internalGetMutableCompletedReassigments().ensureBuilderMap(); - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.ReassignmentOrBuilder entry = builderMap.get(key); - if (entry == null) { - entry = org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.newBuilder(); - builderMap.put(key, entry); - } - if (entry instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) { - entry = ((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) entry).toBuilder(); - builderMap.put(key, entry); - } - return (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder) entry; - } - - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - // @@protoc_insertion_point(builder_scope:org.jbpm.flow.serialization.protobuf.HumanTaskWorkItemData) - } - - // @@protoc_insertion_point(class_scope:org.jbpm.flow.serialization.protobuf.HumanTaskWorkItemData) - private static final org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData(); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public HumanTaskWorkItemData parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - Builder builder = newBuilder(); - try { - builder.mergeFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException(e) - .setUnfinishedMessage(builder.buildPartial()); - } - return builder.buildPartial(); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface CommentOrBuilder extends - // @@protoc_insertion_point(interface_extends:org.jbpm.flow.serialization.protobuf.Comment) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - * - * @return The id. - */ - java.lang.String getId(); - - /** - * string id = 1; - * - * @return The bytes for id. - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * optional string content = 2; - * - * @return Whether the content field is set. - */ - boolean hasContent(); - - /** - * optional string content = 2; - * - * @return The content. - */ - java.lang.String getContent(); - - /** - * optional string content = 2; - * - * @return The bytes for content. - */ - com.google.protobuf.ByteString - getContentBytes(); - - /** - * optional int64 updatedAt = 3; - * - * @return Whether the updatedAt field is set. - */ - boolean hasUpdatedAt(); - - /** - * optional int64 updatedAt = 3; - * - * @return The updatedAt. - */ - long getUpdatedAt(); - - /** - * optional string updatedBy = 4; - * - * @return Whether the updatedBy field is set. - */ - boolean hasUpdatedBy(); - - /** - * optional string updatedBy = 4; - * - * @return The updatedBy. - */ - java.lang.String getUpdatedBy(); - - /** - * optional string updatedBy = 4; - * - * @return The bytes for updatedBy. - */ - com.google.protobuf.ByteString - getUpdatedByBytes(); - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Comment} - */ - public static final class Comment extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:org.jbpm.flow.serialization.protobuf.Comment) - CommentOrBuilder { - private static final long serialVersionUID = 0L; - - // Use Comment.newBuilder() to construct. - private Comment(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - - private Comment() { - id_ = ""; - content_ = ""; - updatedBy_ = ""; - } - - @java.lang.Override - @SuppressWarnings({ "unused" }) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new Comment(); - } - - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Comment_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Comment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder.class); - } - - private int bitField0_; - public static final int ID_FIELD_NUMBER = 1; - @SuppressWarnings("serial") - private volatile java.lang.Object id_ = ""; - - /** - * string id = 1; - * - * @return The id. - */ - @java.lang.Override - public java.lang.String getId() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - - /** - * string id = 1; - * - * @return The bytes for id. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int CONTENT_FIELD_NUMBER = 2; - @SuppressWarnings("serial") - private volatile java.lang.Object content_ = ""; - - /** - * optional string content = 2; - * - * @return Whether the content field is set. - */ - @java.lang.Override - public boolean hasContent() { - return ((bitField0_ & 0x00000001) != 0); - } - - /** - * optional string content = 2; - * - * @return The content. - */ - @java.lang.Override - public java.lang.String getContent() { - java.lang.Object ref = content_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - content_ = s; - return s; - } - } - - /** - * optional string content = 2; - * - * @return The bytes for content. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getContentBytes() { - java.lang.Object ref = content_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - content_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int UPDATEDAT_FIELD_NUMBER = 3; - private long updatedAt_ = 0L; - - /** - * optional int64 updatedAt = 3; - * - * @return Whether the updatedAt field is set. - */ - @java.lang.Override - public boolean hasUpdatedAt() { - return ((bitField0_ & 0x00000002) != 0); - } - - /** - * optional int64 updatedAt = 3; - * - * @return The updatedAt. - */ - @java.lang.Override - public long getUpdatedAt() { - return updatedAt_; - } - - public static final int UPDATEDBY_FIELD_NUMBER = 4; - @SuppressWarnings("serial") - private volatile java.lang.Object updatedBy_ = ""; - - /** - * optional string updatedBy = 4; - * - * @return Whether the updatedBy field is set. - */ - @java.lang.Override - public boolean hasUpdatedBy() { - return ((bitField0_ & 0x00000004) != 0); - } - - /** - * optional string updatedBy = 4; - * - * @return The updatedBy. - */ - @java.lang.Override - public java.lang.String getUpdatedBy() { - java.lang.Object ref = updatedBy_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - updatedBy_ = s; - return s; - } - } - - /** - * optional string updatedBy = 4; - * - * @return The bytes for updatedBy. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getUpdatedByBytes() { - java.lang.Object ref = updatedBy_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - updatedBy_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) - return true; - if (isInitialized == 0) - return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (((bitField0_ & 0x00000001) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, content_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeInt64(3, updatedAt_); - } - if (((bitField0_ & 0x00000004) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 4, updatedBy_); - } - getUnknownFields().writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) - return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, content_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeInt64Size(3, updatedAt_); - } - if (((bitField0_ & 0x00000004) != 0)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, updatedBy_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment)) { - return super.equals(obj); - } - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment other = (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment) obj; - - if (!getId() - .equals(other.getId())) - return false; - if (hasContent() != other.hasContent()) - return false; - if (hasContent()) { - if (!getContent() - .equals(other.getContent())) - return false; - } - if (hasUpdatedAt() != other.hasUpdatedAt()) - return false; - if (hasUpdatedAt()) { - if (getUpdatedAt() != other.getUpdatedAt()) - return false; - } - if (hasUpdatedBy() != other.hasUpdatedBy()) - return false; - if (hasUpdatedBy()) { - if (!getUpdatedBy() - .equals(other.getUpdatedBy())) - return false; - } - if (!getUnknownFields().equals(other.getUnknownFields())) - return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - if (hasContent()) { - hash = (37 * hash) + CONTENT_FIELD_NUMBER; - hash = (53 * hash) + getContent().hashCode(); - } - if (hasUpdatedAt()) { - hash = (37 * hash) + UPDATEDAT_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - getUpdatedAt()); - } - if (hasUpdatedBy()) { - hash = (37 * hash) + UPDATEDBY_FIELD_NUMBER; - hash = (53 * hash) + getUpdatedBy().hashCode(); - } - hash = (29 * hash) + getUnknownFields().hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { - return newBuilder(); - } - - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - - public static Builder newBuilder(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() - : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Comment} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:org.jbpm.flow.serialization.protobuf.Comment) - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.CommentOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Comment_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Comment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.Builder.class); - } - - // Construct using org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.newBuilder() - private Builder() { - - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - - } - - @java.lang.Override - public Builder clear() { - super.clear(); - bitField0_ = 0; - id_ = ""; - content_ = ""; - updatedAt_ = 0L; - updatedBy_ = ""; - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Comment_descriptor; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment getDefaultInstanceForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.getDefaultInstance(); - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment build() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment buildPartial() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment result = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment(this); - if (bitField0_ != 0) { - buildPartial0(result); - } - onBuilt(); - return result; - } - - private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment result) { - int from_bitField0_ = bitField0_; - if (((from_bitField0_ & 0x00000001) != 0)) { - result.id_ = id_; - } - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.content_ = content_; - to_bitField0_ |= 0x00000001; - } - if (((from_bitField0_ & 0x00000004) != 0)) { - result.updatedAt_ = updatedAt_; - to_bitField0_ |= 0x00000002; - } - if (((from_bitField0_ & 0x00000008) != 0)) { - result.updatedBy_ = updatedBy_; - to_bitField0_ |= 0x00000004; - } - result.bitField0_ |= to_bitField0_; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment) { - return mergeFrom((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment) other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment other) { - if (other == org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment.getDefaultInstance()) - return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - bitField0_ |= 0x00000001; - onChanged(); - } - if (other.hasContent()) { - content_ = other.content_; - bitField0_ |= 0x00000002; - onChanged(); - } - if (other.hasUpdatedAt()) { - setUpdatedAt(other.getUpdatedAt()); - } - if (other.hasUpdatedBy()) { - updatedBy_ = other.updatedBy_; - bitField0_ |= 0x00000008; - onChanged(); - } - this.mergeUnknownFields(other.getUnknownFields()); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - id_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000001; - break; - } // case 10 - case 18: { - content_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000002; - break; - } // case 18 - case 24: { - updatedAt_ = input.readInt64(); - bitField0_ |= 0x00000004; - break; - } // case 24 - case 34: { - updatedBy_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000008; - break; - } // case 34 - default: { - if (!super.parseUnknownField(input, extensionRegistry, tag)) { - done = true; // was an endgroup tag - } - break; - } // default: - } // switch (tag) - } // while (!done) - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.unwrapIOException(); - } finally { - onChanged(); - } // finally - return this; - } - - private int bitField0_; - - private java.lang.Object id_ = ""; - - /** - * string id = 1; - * - * @return The id. - */ - public java.lang.String getId() { - java.lang.Object ref = id_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * string id = 1; - * - * @return The bytes for id. - */ - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * string id = 1; - * - * @param value The id to set. - * @return This builder for chaining. - */ - public Builder setId( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - id_ = value; - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - /** - * string id = 1; - * - * @return This builder for chaining. - */ - public Builder clearId() { - id_ = getDefaultInstance().getId(); - bitField0_ = (bitField0_ & ~0x00000001); - onChanged(); - return this; - } - - /** - * string id = 1; - * - * @param value The bytes for id to set. - * @return This builder for chaining. - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - id_ = value; - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - private java.lang.Object content_ = ""; - - /** - * optional string content = 2; - * - * @return Whether the content field is set. - */ - public boolean hasContent() { - return ((bitField0_ & 0x00000002) != 0); - } - - /** - * optional string content = 2; - * - * @return The content. - */ - public java.lang.String getContent() { - java.lang.Object ref = content_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - content_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * optional string content = 2; - * - * @return The bytes for content. - */ - public com.google.protobuf.ByteString - getContentBytes() { - java.lang.Object ref = content_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - content_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * optional string content = 2; - * - * @param value The content to set. - * @return This builder for chaining. - */ - public Builder setContent( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - content_ = value; - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - /** - * optional string content = 2; - * - * @return This builder for chaining. - */ - public Builder clearContent() { - content_ = getDefaultInstance().getContent(); - bitField0_ = (bitField0_ & ~0x00000002); - onChanged(); - return this; - } - - /** - * optional string content = 2; - * - * @param value The bytes for content to set. - * @return This builder for chaining. - */ - public Builder setContentBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - content_ = value; - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - private long updatedAt_; - - /** - * optional int64 updatedAt = 3; - * - * @return Whether the updatedAt field is set. - */ - @java.lang.Override - public boolean hasUpdatedAt() { - return ((bitField0_ & 0x00000004) != 0); - } - - /** - * optional int64 updatedAt = 3; - * - * @return The updatedAt. - */ - @java.lang.Override - public long getUpdatedAt() { - return updatedAt_; - } - - /** - * optional int64 updatedAt = 3; - * - * @param value The updatedAt to set. - * @return This builder for chaining. - */ - public Builder setUpdatedAt(long value) { - - updatedAt_ = value; - bitField0_ |= 0x00000004; - onChanged(); - return this; - } - - /** - * optional int64 updatedAt = 3; - * - * @return This builder for chaining. - */ - public Builder clearUpdatedAt() { - bitField0_ = (bitField0_ & ~0x00000004); - updatedAt_ = 0L; - onChanged(); - return this; - } - - private java.lang.Object updatedBy_ = ""; - - /** - * optional string updatedBy = 4; - * - * @return Whether the updatedBy field is set. - */ - public boolean hasUpdatedBy() { - return ((bitField0_ & 0x00000008) != 0); - } - - /** - * optional string updatedBy = 4; - * - * @return The updatedBy. - */ - public java.lang.String getUpdatedBy() { - java.lang.Object ref = updatedBy_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - updatedBy_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * optional string updatedBy = 4; - * - * @return The bytes for updatedBy. - */ - public com.google.protobuf.ByteString - getUpdatedByBytes() { - java.lang.Object ref = updatedBy_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - updatedBy_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * optional string updatedBy = 4; - * - * @param value The updatedBy to set. - * @return This builder for chaining. - */ - public Builder setUpdatedBy( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - updatedBy_ = value; - bitField0_ |= 0x00000008; - onChanged(); - return this; - } - - /** - * optional string updatedBy = 4; - * - * @return This builder for chaining. - */ - public Builder clearUpdatedBy() { - updatedBy_ = getDefaultInstance().getUpdatedBy(); - bitField0_ = (bitField0_ & ~0x00000008); - onChanged(); - return this; - } - - /** - * optional string updatedBy = 4; - * - * @param value The bytes for updatedBy to set. - * @return This builder for chaining. - */ - public Builder setUpdatedByBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - updatedBy_ = value; - bitField0_ |= 0x00000008; - onChanged(); - return this; - } - - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - // @@protoc_insertion_point(builder_scope:org.jbpm.flow.serialization.protobuf.Comment) - } - - // @@protoc_insertion_point(class_scope:org.jbpm.flow.serialization.protobuf.Comment) - private static final org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment(); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Comment parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - Builder builder = newBuilder(); - try { - builder.mergeFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException(e) - .setUnfinishedMessage(builder.buildPartial()); - } - return builder.buildPartial(); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Comment getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface AttachmentOrBuilder extends - // @@protoc_insertion_point(interface_extends:org.jbpm.flow.serialization.protobuf.Attachment) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - * - * @return The id. - */ - java.lang.String getId(); - - /** - * string id = 1; - * - * @return The bytes for id. - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * optional string content = 2; - * - * @return Whether the content field is set. - */ - boolean hasContent(); - - /** - * optional string content = 2; - * - * @return The content. - */ - java.lang.String getContent(); - - /** - * optional string content = 2; - * - * @return The bytes for content. - */ - com.google.protobuf.ByteString - getContentBytes(); - - /** - * optional int64 updatedAt = 3; - * - * @return Whether the updatedAt field is set. - */ - boolean hasUpdatedAt(); - - /** - * optional int64 updatedAt = 3; - * - * @return The updatedAt. - */ - long getUpdatedAt(); - - /** - * optional string updatedBy = 4; - * - * @return Whether the updatedBy field is set. - */ - boolean hasUpdatedBy(); - - /** - * optional string updatedBy = 4; - * - * @return The updatedBy. - */ - java.lang.String getUpdatedBy(); - - /** - * optional string updatedBy = 4; - * - * @return The bytes for updatedBy. - */ - com.google.protobuf.ByteString - getUpdatedByBytes(); - - /** - * optional string name = 5; - * - * @return Whether the name field is set. - */ - boolean hasName(); - - /** - * optional string name = 5; - * - * @return The name. - */ - java.lang.String getName(); - - /** - * optional string name = 5; - * - * @return The bytes for name. - */ - com.google.protobuf.ByteString - getNameBytes(); - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Attachment} - */ - public static final class Attachment extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:org.jbpm.flow.serialization.protobuf.Attachment) - AttachmentOrBuilder { - private static final long serialVersionUID = 0L; - - // Use Attachment.newBuilder() to construct. - private Attachment(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - - private Attachment() { - id_ = ""; - content_ = ""; - updatedBy_ = ""; - name_ = ""; - } - - @java.lang.Override - @SuppressWarnings({ "unused" }) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new Attachment(); - } - - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Attachment_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Attachment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder.class); - } - - private int bitField0_; - public static final int ID_FIELD_NUMBER = 1; - @SuppressWarnings("serial") - private volatile java.lang.Object id_ = ""; - - /** - * string id = 1; - * - * @return The id. - */ - @java.lang.Override - public java.lang.String getId() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - - /** - * string id = 1; - * - * @return The bytes for id. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int CONTENT_FIELD_NUMBER = 2; - @SuppressWarnings("serial") - private volatile java.lang.Object content_ = ""; - - /** - * optional string content = 2; - * - * @return Whether the content field is set. - */ - @java.lang.Override - public boolean hasContent() { - return ((bitField0_ & 0x00000001) != 0); - } - - /** - * optional string content = 2; - * - * @return The content. - */ - @java.lang.Override - public java.lang.String getContent() { - java.lang.Object ref = content_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - content_ = s; - return s; - } - } - - /** - * optional string content = 2; - * - * @return The bytes for content. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getContentBytes() { - java.lang.Object ref = content_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - content_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int UPDATEDAT_FIELD_NUMBER = 3; - private long updatedAt_ = 0L; - - /** - * optional int64 updatedAt = 3; - * - * @return Whether the updatedAt field is set. - */ - @java.lang.Override - public boolean hasUpdatedAt() { - return ((bitField0_ & 0x00000002) != 0); - } - - /** - * optional int64 updatedAt = 3; - * - * @return The updatedAt. - */ - @java.lang.Override - public long getUpdatedAt() { - return updatedAt_; - } - - public static final int UPDATEDBY_FIELD_NUMBER = 4; - @SuppressWarnings("serial") - private volatile java.lang.Object updatedBy_ = ""; - - /** - * optional string updatedBy = 4; - * - * @return Whether the updatedBy field is set. - */ - @java.lang.Override - public boolean hasUpdatedBy() { - return ((bitField0_ & 0x00000004) != 0); - } - - /** - * optional string updatedBy = 4; - * - * @return The updatedBy. - */ - @java.lang.Override - public java.lang.String getUpdatedBy() { - java.lang.Object ref = updatedBy_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - updatedBy_ = s; - return s; - } - } - - /** - * optional string updatedBy = 4; - * - * @return The bytes for updatedBy. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getUpdatedByBytes() { - java.lang.Object ref = updatedBy_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - updatedBy_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int NAME_FIELD_NUMBER = 5; - @SuppressWarnings("serial") - private volatile java.lang.Object name_ = ""; - - /** - * optional string name = 5; - * - * @return Whether the name field is set. - */ - @java.lang.Override - public boolean hasName() { - return ((bitField0_ & 0x00000008) != 0); - } - - /** - * optional string name = 5; - * - * @return The name. - */ - @java.lang.Override - public java.lang.String getName() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - name_ = s; - return s; - } - } - - /** - * optional string name = 5; - * - * @return The bytes for name. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) - return true; - if (isInitialized == 0) - return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (((bitField0_ & 0x00000001) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, content_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeInt64(3, updatedAt_); - } - if (((bitField0_ & 0x00000004) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 4, updatedBy_); - } - if (((bitField0_ & 0x00000008) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 5, name_); - } - getUnknownFields().writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) - return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, content_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeInt64Size(3, updatedAt_); - } - if (((bitField0_ & 0x00000004) != 0)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, updatedBy_); - } - if (((bitField0_ & 0x00000008) != 0)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, name_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment)) { - return super.equals(obj); - } - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment other = (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment) obj; - - if (!getId() - .equals(other.getId())) - return false; - if (hasContent() != other.hasContent()) - return false; - if (hasContent()) { - if (!getContent() - .equals(other.getContent())) - return false; - } - if (hasUpdatedAt() != other.hasUpdatedAt()) - return false; - if (hasUpdatedAt()) { - if (getUpdatedAt() != other.getUpdatedAt()) - return false; - } - if (hasUpdatedBy() != other.hasUpdatedBy()) - return false; - if (hasUpdatedBy()) { - if (!getUpdatedBy() - .equals(other.getUpdatedBy())) - return false; - } - if (hasName() != other.hasName()) - return false; - if (hasName()) { - if (!getName() - .equals(other.getName())) - return false; - } - if (!getUnknownFields().equals(other.getUnknownFields())) - return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - if (hasContent()) { - hash = (37 * hash) + CONTENT_FIELD_NUMBER; - hash = (53 * hash) + getContent().hashCode(); - } - if (hasUpdatedAt()) { - hash = (37 * hash) + UPDATEDAT_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - getUpdatedAt()); - } - if (hasUpdatedBy()) { - hash = (37 * hash) + UPDATEDBY_FIELD_NUMBER; - hash = (53 * hash) + getUpdatedBy().hashCode(); - } - if (hasName()) { - hash = (37 * hash) + NAME_FIELD_NUMBER; - hash = (53 * hash) + getName().hashCode(); - } - hash = (29 * hash) + getUnknownFields().hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { - return newBuilder(); - } - - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - - public static Builder newBuilder(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() - : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Attachment} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:org.jbpm.flow.serialization.protobuf.Attachment) - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.AttachmentOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Attachment_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Attachment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.Builder.class); - } - - // Construct using org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.newBuilder() - private Builder() { - - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - - } - - @java.lang.Override - public Builder clear() { - super.clear(); - bitField0_ = 0; - id_ = ""; - content_ = ""; - updatedAt_ = 0L; - updatedBy_ = ""; - name_ = ""; - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Attachment_descriptor; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment getDefaultInstanceForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.getDefaultInstance(); - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment build() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment buildPartial() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment result = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment(this); - if (bitField0_ != 0) { - buildPartial0(result); - } - onBuilt(); - return result; - } - - private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment result) { - int from_bitField0_ = bitField0_; - if (((from_bitField0_ & 0x00000001) != 0)) { - result.id_ = id_; - } - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.content_ = content_; - to_bitField0_ |= 0x00000001; - } - if (((from_bitField0_ & 0x00000004) != 0)) { - result.updatedAt_ = updatedAt_; - to_bitField0_ |= 0x00000002; - } - if (((from_bitField0_ & 0x00000008) != 0)) { - result.updatedBy_ = updatedBy_; - to_bitField0_ |= 0x00000004; - } - if (((from_bitField0_ & 0x00000010) != 0)) { - result.name_ = name_; - to_bitField0_ |= 0x00000008; - } - result.bitField0_ |= to_bitField0_; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment) { - return mergeFrom((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment) other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment other) { - if (other == org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment.getDefaultInstance()) - return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - bitField0_ |= 0x00000001; - onChanged(); - } - if (other.hasContent()) { - content_ = other.content_; - bitField0_ |= 0x00000002; - onChanged(); - } - if (other.hasUpdatedAt()) { - setUpdatedAt(other.getUpdatedAt()); - } - if (other.hasUpdatedBy()) { - updatedBy_ = other.updatedBy_; - bitField0_ |= 0x00000008; - onChanged(); - } - if (other.hasName()) { - name_ = other.name_; - bitField0_ |= 0x00000010; - onChanged(); - } - this.mergeUnknownFields(other.getUnknownFields()); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - id_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000001; - break; - } // case 10 - case 18: { - content_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000002; - break; - } // case 18 - case 24: { - updatedAt_ = input.readInt64(); - bitField0_ |= 0x00000004; - break; - } // case 24 - case 34: { - updatedBy_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000008; - break; - } // case 34 - case 42: { - name_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000010; - break; - } // case 42 - default: { - if (!super.parseUnknownField(input, extensionRegistry, tag)) { - done = true; // was an endgroup tag - } - break; - } // default: - } // switch (tag) - } // while (!done) - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.unwrapIOException(); - } finally { - onChanged(); - } // finally - return this; - } - - private int bitField0_; - - private java.lang.Object id_ = ""; - - /** - * string id = 1; - * - * @return The id. - */ - public java.lang.String getId() { - java.lang.Object ref = id_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * string id = 1; - * - * @return The bytes for id. - */ - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * string id = 1; - * - * @param value The id to set. - * @return This builder for chaining. - */ - public Builder setId( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - id_ = value; - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - /** - * string id = 1; - * - * @return This builder for chaining. - */ - public Builder clearId() { - id_ = getDefaultInstance().getId(); - bitField0_ = (bitField0_ & ~0x00000001); - onChanged(); - return this; - } - - /** - * string id = 1; - * - * @param value The bytes for id to set. - * @return This builder for chaining. - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - id_ = value; - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - private java.lang.Object content_ = ""; - - /** - * optional string content = 2; - * - * @return Whether the content field is set. - */ - public boolean hasContent() { - return ((bitField0_ & 0x00000002) != 0); - } - - /** - * optional string content = 2; - * - * @return The content. - */ - public java.lang.String getContent() { - java.lang.Object ref = content_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - content_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * optional string content = 2; - * - * @return The bytes for content. - */ - public com.google.protobuf.ByteString - getContentBytes() { - java.lang.Object ref = content_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - content_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * optional string content = 2; - * - * @param value The content to set. - * @return This builder for chaining. - */ - public Builder setContent( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - content_ = value; - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - /** - * optional string content = 2; - * - * @return This builder for chaining. - */ - public Builder clearContent() { - content_ = getDefaultInstance().getContent(); - bitField0_ = (bitField0_ & ~0x00000002); - onChanged(); - return this; - } - - /** - * optional string content = 2; - * - * @param value The bytes for content to set. - * @return This builder for chaining. - */ - public Builder setContentBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - content_ = value; - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - private long updatedAt_; - - /** - * optional int64 updatedAt = 3; - * - * @return Whether the updatedAt field is set. - */ - @java.lang.Override - public boolean hasUpdatedAt() { - return ((bitField0_ & 0x00000004) != 0); - } - - /** - * optional int64 updatedAt = 3; - * - * @return The updatedAt. - */ - @java.lang.Override - public long getUpdatedAt() { - return updatedAt_; - } - - /** - * optional int64 updatedAt = 3; - * - * @param value The updatedAt to set. - * @return This builder for chaining. - */ - public Builder setUpdatedAt(long value) { - - updatedAt_ = value; - bitField0_ |= 0x00000004; - onChanged(); - return this; - } - - /** - * optional int64 updatedAt = 3; - * - * @return This builder for chaining. - */ - public Builder clearUpdatedAt() { - bitField0_ = (bitField0_ & ~0x00000004); - updatedAt_ = 0L; - onChanged(); - return this; - } - - private java.lang.Object updatedBy_ = ""; - - /** - * optional string updatedBy = 4; - * - * @return Whether the updatedBy field is set. - */ - public boolean hasUpdatedBy() { - return ((bitField0_ & 0x00000008) != 0); - } - - /** - * optional string updatedBy = 4; - * - * @return The updatedBy. - */ - public java.lang.String getUpdatedBy() { - java.lang.Object ref = updatedBy_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - updatedBy_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * optional string updatedBy = 4; - * - * @return The bytes for updatedBy. - */ - public com.google.protobuf.ByteString - getUpdatedByBytes() { - java.lang.Object ref = updatedBy_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - updatedBy_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * optional string updatedBy = 4; - * - * @param value The updatedBy to set. - * @return This builder for chaining. - */ - public Builder setUpdatedBy( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - updatedBy_ = value; - bitField0_ |= 0x00000008; - onChanged(); - return this; - } - - /** - * optional string updatedBy = 4; - * - * @return This builder for chaining. - */ - public Builder clearUpdatedBy() { - updatedBy_ = getDefaultInstance().getUpdatedBy(); - bitField0_ = (bitField0_ & ~0x00000008); - onChanged(); - return this; - } - - /** - * optional string updatedBy = 4; - * - * @param value The bytes for updatedBy to set. - * @return This builder for chaining. - */ - public Builder setUpdatedByBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - updatedBy_ = value; - bitField0_ |= 0x00000008; - onChanged(); - return this; - } - - private java.lang.Object name_ = ""; - - /** - * optional string name = 5; - * - * @return Whether the name field is set. - */ - public boolean hasName() { - return ((bitField0_ & 0x00000010) != 0); - } - - /** - * optional string name = 5; - * - * @return The name. - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - name_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - - /** - * optional string name = 5; - * - * @return The bytes for name. - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - /** - * optional string name = 5; - * - * @param value The name to set. - * @return This builder for chaining. - */ - public Builder setName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - name_ = value; - bitField0_ |= 0x00000010; - onChanged(); - return this; - } - - /** - * optional string name = 5; - * - * @return This builder for chaining. - */ - public Builder clearName() { - name_ = getDefaultInstance().getName(); - bitField0_ = (bitField0_ & ~0x00000010); - onChanged(); - return this; - } - - /** - * optional string name = 5; - * - * @param value The bytes for name to set. - * @return This builder for chaining. - */ - public Builder setNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - name_ = value; - bitField0_ |= 0x00000010; - onChanged(); - return this; - } - - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - // @@protoc_insertion_point(builder_scope:org.jbpm.flow.serialization.protobuf.Attachment) - } - - // @@protoc_insertion_point(class_scope:org.jbpm.flow.serialization.protobuf.Attachment) - private static final org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment(); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Attachment parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - Builder builder = newBuilder(); - try { - builder.mergeFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException(e) - .setUnfinishedMessage(builder.buildPartial()); - } - return builder.buildPartial(); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Attachment getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface DeadlineOrBuilder extends - // @@protoc_insertion_point(interface_extends:org.jbpm.flow.serialization.protobuf.Deadline) - com.google.protobuf.MessageOrBuilder { - - /** - * map<string, string> content = 1; - */ - int getContentCount(); - - /** - * map<string, string> content = 1; - */ - boolean containsContent( - java.lang.String key); - - /** - * Use {@link #getContentMap()} instead. - */ - @java.lang.Deprecated - java.util.Map - getContent(); - - /** - * map<string, string> content = 1; - */ - java.util.Map - getContentMap(); - - /** - * map<string, string> content = 1; - */ - /* nullable */ - java.lang.String getContentOrDefault( - java.lang.String key, - /* nullable */ - java.lang.String defaultValue); - - /** - * map<string, string> content = 1; - */ - java.lang.String getContentOrThrow( - java.lang.String key); - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Deadline} - */ - public static final class Deadline extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:org.jbpm.flow.serialization.protobuf.Deadline) - DeadlineOrBuilder { - private static final long serialVersionUID = 0L; - - // Use Deadline.newBuilder() to construct. - private Deadline(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - - private Deadline() { - } - - @java.lang.Override - @SuppressWarnings({ "unused" }) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new Deadline(); - } - - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Deadline_descriptor; - } - - @SuppressWarnings({ "rawtypes" }) - @java.lang.Override - protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( - int number) { - switch (number) { - case 1: - return internalGetContent(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Deadline_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder.class); - } - - public static final int CONTENT_FIELD_NUMBER = 1; - - private static final class ContentDefaultEntryHolder { - static final com.google.protobuf.MapEntry defaultEntry = - com.google.protobuf.MapEntry. newDefaultInstance( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Deadline_ContentEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.STRING, - ""); - } - - @SuppressWarnings("serial") - private com.google.protobuf.MapField content_; - - private com.google.protobuf.MapField - internalGetContent() { - if (content_ == null) { - return com.google.protobuf.MapField.emptyMapField( - ContentDefaultEntryHolder.defaultEntry); - } - return content_; - } - - public int getContentCount() { - return internalGetContent().getMap().size(); - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public boolean containsContent( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetContent().getMap().containsKey(key); - } - - /** - * Use {@link #getContentMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getContent() { - return getContentMap(); - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public java.util.Map getContentMap() { - return internalGetContent().getMap(); - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public /* nullable */ - java.lang.String getContentOrDefault( - java.lang.String key, - /* nullable */ - java.lang.String defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetContent().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public java.lang.String getContentOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetContent().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return map.get(key); - } - - private byte memoizedIsInitialized = -1; - - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) - return true; - if (isInitialized == 0) - return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetContent(), - ContentDefaultEntryHolder.defaultEntry, - 1); - getUnknownFields().writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) - return size; - - size = 0; - for (java.util.Map.Entry entry : internalGetContent().getMap().entrySet()) { - com.google.protobuf.MapEntry content__ = ContentDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, content__); - } - size += getUnknownFields().getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline)) { - return super.equals(obj); - } - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline other = (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) obj; - - if (!internalGetContent().equals( - other.internalGetContent())) - return false; - if (!getUnknownFields().equals(other.getUnknownFields())) - return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (!internalGetContent().getMap().isEmpty()) { - hash = (37 * hash) + CONTENT_FIELD_NUMBER; - hash = (53 * hash) + internalGetContent().hashCode(); - } - hash = (29 * hash) + getUnknownFields().hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { - return newBuilder(); - } - - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - - public static Builder newBuilder(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() - : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Deadline} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:org.jbpm.flow.serialization.protobuf.Deadline) - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.DeadlineOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Deadline_descriptor; - } - - @SuppressWarnings({ "rawtypes" }) - protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( - int number) { - switch (number) { - case 1: - return internalGetContent(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - - @SuppressWarnings({ "rawtypes" }) - protected com.google.protobuf.MapFieldReflectionAccessor internalGetMutableMapFieldReflection( - int number) { - switch (number) { - case 1: - return internalGetMutableContent(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Deadline_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.Builder.class); - } - - // Construct using org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.newBuilder() - private Builder() { - - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - - } - - @java.lang.Override - public Builder clear() { - super.clear(); - bitField0_ = 0; - internalGetMutableContent().clear(); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Deadline_descriptor; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getDefaultInstanceForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.getDefaultInstance(); - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline build() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline buildPartial() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline result = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline(this); - if (bitField0_ != 0) { - buildPartial0(result); - } - onBuilt(); - return result; - } - - private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline result) { - int from_bitField0_ = bitField0_; - if (((from_bitField0_ & 0x00000001) != 0)) { - result.content_ = internalGetContent(); - result.content_.makeImmutable(); - } - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) { - return mergeFrom((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline) other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline other) { - if (other == org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline.getDefaultInstance()) - return this; - internalGetMutableContent().mergeFrom( - other.internalGetContent()); - bitField0_ |= 0x00000001; - this.mergeUnknownFields(other.getUnknownFields()); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - com.google.protobuf.MapEntry content__ = input.readMessage( - ContentDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - internalGetMutableContent().getMutableMap().put( - content__.getKey(), content__.getValue()); - bitField0_ |= 0x00000001; - break; - } // case 10 - default: { - if (!super.parseUnknownField(input, extensionRegistry, tag)) { - done = true; // was an endgroup tag - } - break; - } // default: - } // switch (tag) - } // while (!done) - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.unwrapIOException(); - } finally { - onChanged(); - } // finally - return this; - } - - private int bitField0_; - - private com.google.protobuf.MapField content_; - - private com.google.protobuf.MapField - internalGetContent() { - if (content_ == null) { - return com.google.protobuf.MapField.emptyMapField( - ContentDefaultEntryHolder.defaultEntry); - } - return content_; - } - - private com.google.protobuf.MapField - internalGetMutableContent() { - if (content_ == null) { - content_ = com.google.protobuf.MapField.newMapField( - ContentDefaultEntryHolder.defaultEntry); - } - if (!content_.isMutable()) { - content_ = content_.copy(); - } - bitField0_ |= 0x00000001; - onChanged(); - return content_; - } - - public int getContentCount() { - return internalGetContent().getMap().size(); - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public boolean containsContent( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - return internalGetContent().getMap().containsKey(key); - } - - /** - * Use {@link #getContentMap()} instead. - */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getContent() { - return getContentMap(); - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public java.util.Map getContentMap() { - return internalGetContent().getMap(); - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public /* nullable */ - java.lang.String getContentOrDefault( - java.lang.String key, - /* nullable */ - java.lang.String defaultValue) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetContent().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * map<string, string> content = 1; - */ - @java.lang.Override - public java.lang.String getContentOrThrow( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - java.util.Map map = - internalGetContent().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return map.get(key); - } - - public Builder clearContent() { - bitField0_ = (bitField0_ & ~0x00000001); - internalGetMutableContent().getMutableMap() - .clear(); - return this; - } - - /** - * map<string, string> content = 1; - */ - public Builder removeContent( - java.lang.String key) { - if (key == null) { - throw new NullPointerException("map key"); - } - internalGetMutableContent().getMutableMap() - .remove(key); - return this; - } - - /** - * Use alternate mutation accessors instead. - */ - @java.lang.Deprecated - public java.util.Map - getMutableContent() { - bitField0_ |= 0x00000001; - return internalGetMutableContent().getMutableMap(); - } - - /** - * map<string, string> content = 1; - */ - public Builder putContent( - java.lang.String key, - java.lang.String value) { - if (key == null) { - throw new NullPointerException("map key"); - } - if (value == null) { - throw new NullPointerException("map value"); - } - internalGetMutableContent().getMutableMap() - .put(key, value); - bitField0_ |= 0x00000001; - return this; - } - - /** - * map<string, string> content = 1; - */ - public Builder putAllContent( - java.util.Map values) { - internalGetMutableContent().getMutableMap() - .putAll(values); - bitField0_ |= 0x00000001; - return this; - } - - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - // @@protoc_insertion_point(builder_scope:org.jbpm.flow.serialization.protobuf.Deadline) - } - - // @@protoc_insertion_point(class_scope:org.jbpm.flow.serialization.protobuf.Deadline) - private static final org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline(); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Deadline parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - Builder builder = newBuilder(); - try { - builder.mergeFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException(e) - .setUnfinishedMessage(builder.buildPartial()); - } - return builder.buildPartial(); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Deadline getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface ReassignmentOrBuilder extends - // @@protoc_insertion_point(interface_extends:org.jbpm.flow.serialization.protobuf.Reassignment) - com.google.protobuf.MessageOrBuilder { - - /** - * repeated string users = 1; - * - * @return A list containing the users. - */ - java.util.List - getUsersList(); - - /** - * repeated string users = 1; - * - * @return The count of users. - */ - int getUsersCount(); - - /** - * repeated string users = 1; - * - * @param index The index of the element to return. - * @return The users at the given index. - */ - java.lang.String getUsers(int index); - - /** - * repeated string users = 1; - * - * @param index The index of the value to return. - * @return The bytes of the users at the given index. - */ - com.google.protobuf.ByteString - getUsersBytes(int index); - - /** - * repeated string groups = 2; - * - * @return A list containing the groups. - */ - java.util.List - getGroupsList(); - - /** - * repeated string groups = 2; - * - * @return The count of groups. - */ - int getGroupsCount(); - - /** - * repeated string groups = 2; - * - * @param index The index of the element to return. - * @return The groups at the given index. - */ - java.lang.String getGroups(int index); - - /** - * repeated string groups = 2; - * - * @param index The index of the value to return. - * @return The bytes of the groups at the given index. - */ - com.google.protobuf.ByteString - getGroupsBytes(int index); - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Reassignment} - */ - public static final class Reassignment extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:org.jbpm.flow.serialization.protobuf.Reassignment) - ReassignmentOrBuilder { - private static final long serialVersionUID = 0L; - - // Use Reassignment.newBuilder() to construct. - private Reassignment(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - - private Reassignment() { - users_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - groups_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - } - - @java.lang.Override - @SuppressWarnings({ "unused" }) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new Reassignment(); - } - - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.class, org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder.class); - } - - public static final int USERS_FIELD_NUMBER = 1; - @SuppressWarnings("serial") - private com.google.protobuf.LazyStringArrayList users_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - - /** - * repeated string users = 1; - * - * @return A list containing the users. - */ - public com.google.protobuf.ProtocolStringList - getUsersList() { - return users_; - } - - /** - * repeated string users = 1; - * - * @return The count of users. - */ - public int getUsersCount() { - return users_.size(); - } - - /** - * repeated string users = 1; - * - * @param index The index of the element to return. - * @return The users at the given index. - */ - public java.lang.String getUsers(int index) { - return users_.get(index); - } - - /** - * repeated string users = 1; - * - * @param index The index of the value to return. - * @return The bytes of the users at the given index. - */ - public com.google.protobuf.ByteString - getUsersBytes(int index) { - return users_.getByteString(index); - } - - public static final int GROUPS_FIELD_NUMBER = 2; - @SuppressWarnings("serial") - private com.google.protobuf.LazyStringArrayList groups_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - - /** - * repeated string groups = 2; - * - * @return A list containing the groups. - */ - public com.google.protobuf.ProtocolStringList - getGroupsList() { - return groups_; - } - - /** - * repeated string groups = 2; - * - * @return The count of groups. - */ - public int getGroupsCount() { - return groups_.size(); - } - - /** - * repeated string groups = 2; - * - * @param index The index of the element to return. - * @return The groups at the given index. - */ - public java.lang.String getGroups(int index) { - return groups_.get(index); - } - - /** - * repeated string groups = 2; - * - * @param index The index of the value to return. - * @return The bytes of the groups at the given index. - */ - public com.google.protobuf.ByteString - getGroupsBytes(int index) { - return groups_.getByteString(index); - } - - private byte memoizedIsInitialized = -1; - - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) - return true; - if (isInitialized == 0) - return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - for (int i = 0; i < users_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, users_.getRaw(i)); - } - for (int i = 0; i < groups_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, groups_.getRaw(i)); - } - getUnknownFields().writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) - return size; - - size = 0; - { - int dataSize = 0; - for (int i = 0; i < users_.size(); i++) { - dataSize += computeStringSizeNoTag(users_.getRaw(i)); - } - size += dataSize; - size += 1 * getUsersList().size(); - } - { - int dataSize = 0; - for (int i = 0; i < groups_.size(); i++) { - dataSize += computeStringSizeNoTag(groups_.getRaw(i)); - } - size += dataSize; - size += 1 * getGroupsList().size(); - } - size += getUnknownFields().getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment)) { - return super.equals(obj); - } - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment other = (org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) obj; - - if (!getUsersList() - .equals(other.getUsersList())) - return false; - if (!getGroupsList() - .equals(other.getGroupsList())) - return false; - if (!getUnknownFields().equals(other.getUnknownFields())) - return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (getUsersCount() > 0) { - hash = (37 * hash) + USERS_FIELD_NUMBER; - hash = (53 * hash) + getUsersList().hashCode(); - } - if (getGroupsCount() > 0) { - hash = (37 * hash) + GROUPS_FIELD_NUMBER; - hash = (53 * hash) + getGroupsList().hashCode(); - } - hash = (29 * hash) + getUnknownFields().hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { - return newBuilder(); - } - - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - - public static Builder newBuilder(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() - : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - - /** - * Protobuf type {@code org.jbpm.flow.serialization.protobuf.Reassignment} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:org.jbpm.flow.serialization.protobuf.Reassignment) - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.ReassignmentOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.class, - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.Builder.class); - } - - // Construct using org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.newBuilder() - private Builder() { - - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - - } - - @java.lang.Override - public Builder clear() { - super.clear(); - bitField0_ = 0; - users_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - groups_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_descriptor; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getDefaultInstanceForType() { - return org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.getDefaultInstance(); - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment build() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment buildPartial() { - org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment result = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment(this); - if (bitField0_ != 0) { - buildPartial0(result); - } - onBuilt(); - return result; - } - - private void buildPartial0(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment result) { - int from_bitField0_ = bitField0_; - if (((from_bitField0_ & 0x00000001) != 0)) { - users_.makeImmutable(); - result.users_ = users_; - } - if (((from_bitField0_ & 0x00000002) != 0)) { - groups_.makeImmutable(); - result.groups_ = groups_; - } - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) { - return mergeFrom((org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment) other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment other) { - if (other == org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment.getDefaultInstance()) - return this; - if (!other.users_.isEmpty()) { - if (users_.isEmpty()) { - users_ = other.users_; - bitField0_ |= 0x00000001; - } else { - ensureUsersIsMutable(); - users_.addAll(other.users_); - } - onChanged(); - } - if (!other.groups_.isEmpty()) { - if (groups_.isEmpty()) { - groups_ = other.groups_; - bitField0_ |= 0x00000002; - } else { - ensureGroupsIsMutable(); - groups_.addAll(other.groups_); - } - onChanged(); - } - this.mergeUnknownFields(other.getUnknownFields()); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - java.lang.String s = input.readStringRequireUtf8(); - ensureUsersIsMutable(); - users_.add(s); - break; - } // case 10 - case 18: { - java.lang.String s = input.readStringRequireUtf8(); - ensureGroupsIsMutable(); - groups_.add(s); - break; - } // case 18 - default: { - if (!super.parseUnknownField(input, extensionRegistry, tag)) { - done = true; // was an endgroup tag - } - break; - } // default: - } // switch (tag) - } // while (!done) - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.unwrapIOException(); - } finally { - onChanged(); - } // finally - return this; - } - - private int bitField0_; - - private com.google.protobuf.LazyStringArrayList users_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - - private void ensureUsersIsMutable() { - if (!users_.isModifiable()) { - users_ = new com.google.protobuf.LazyStringArrayList(users_); - } - bitField0_ |= 0x00000001; - } - - /** - * repeated string users = 1; - * - * @return A list containing the users. - */ - public com.google.protobuf.ProtocolStringList - getUsersList() { - users_.makeImmutable(); - return users_; - } - - /** - * repeated string users = 1; - * - * @return The count of users. - */ - public int getUsersCount() { - return users_.size(); - } - - /** - * repeated string users = 1; - * - * @param index The index of the element to return. - * @return The users at the given index. - */ - public java.lang.String getUsers(int index) { - return users_.get(index); - } - - /** - * repeated string users = 1; - * - * @param index The index of the value to return. - * @return The bytes of the users at the given index. - */ - public com.google.protobuf.ByteString - getUsersBytes(int index) { - return users_.getByteString(index); - } - - /** - * repeated string users = 1; - * - * @param index The index to set the value at. - * @param value The users to set. - * @return This builder for chaining. - */ - public Builder setUsers( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureUsersIsMutable(); - users_.set(index, value); - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - /** - * repeated string users = 1; - * - * @param value The users to add. - * @return This builder for chaining. - */ - public Builder addUsers( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureUsersIsMutable(); - users_.add(value); - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - /** - * repeated string users = 1; - * - * @param values The users to add. - * @return This builder for chaining. - */ - public Builder addAllUsers( - java.lang.Iterable values) { - ensureUsersIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, users_); - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - /** - * repeated string users = 1; - * - * @return This builder for chaining. - */ - public Builder clearUsers() { - users_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); - ; - onChanged(); - return this; - } - - /** - * repeated string users = 1; - * - * @param value The bytes of the users to add. - * @return This builder for chaining. - */ - public Builder addUsersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - ensureUsersIsMutable(); - users_.add(value); - bitField0_ |= 0x00000001; - onChanged(); - return this; - } - - private com.google.protobuf.LazyStringArrayList groups_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - - private void ensureGroupsIsMutable() { - if (!groups_.isModifiable()) { - groups_ = new com.google.protobuf.LazyStringArrayList(groups_); - } - bitField0_ |= 0x00000002; - } - - /** - * repeated string groups = 2; - * - * @return A list containing the groups. - */ - public com.google.protobuf.ProtocolStringList - getGroupsList() { - groups_.makeImmutable(); - return groups_; - } - - /** - * repeated string groups = 2; - * - * @return The count of groups. - */ - public int getGroupsCount() { - return groups_.size(); - } - - /** - * repeated string groups = 2; - * - * @param index The index of the element to return. - * @return The groups at the given index. - */ - public java.lang.String getGroups(int index) { - return groups_.get(index); - } - - /** - * repeated string groups = 2; - * - * @param index The index of the value to return. - * @return The bytes of the groups at the given index. - */ - public com.google.protobuf.ByteString - getGroupsBytes(int index) { - return groups_.getByteString(index); - } - - /** - * repeated string groups = 2; - * - * @param index The index to set the value at. - * @param value The groups to set. - * @return This builder for chaining. - */ - public Builder setGroups( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureGroupsIsMutable(); - groups_.set(index, value); - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - /** - * repeated string groups = 2; - * - * @param value The groups to add. - * @return This builder for chaining. - */ - public Builder addGroups( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureGroupsIsMutable(); - groups_.add(value); - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - /** - * repeated string groups = 2; - * - * @param values The groups to add. - * @return This builder for chaining. - */ - public Builder addAllGroups( - java.lang.Iterable values) { - ensureGroupsIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, groups_); - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - /** - * repeated string groups = 2; - * - * @return This builder for chaining. - */ - public Builder clearGroups() { - groups_ = - com.google.protobuf.LazyStringArrayList.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); - ; - onChanged(); - return this; - } - - /** - * repeated string groups = 2; - * - * @param value The bytes of the groups to add. - * @return This builder for chaining. - */ - public Builder addGroupsBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - ensureGroupsIsMutable(); - groups_.add(value); - bitField0_ |= 0x00000002; - onChanged(); - return this; - } - - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - // @@protoc_insertion_point(builder_scope:org.jbpm.flow.serialization.protobuf.Reassignment) - } - - // @@protoc_insertion_point(class_scope:org.jbpm.flow.serialization.protobuf.Reassignment) - private static final org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment(); - } - - public static org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Reassignment parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - Builder builder = newBuilder(); - try { - builder.mergeFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException(e) - .setUnfinishedMessage(builder.buildPartial()); - } - return builder.buildPartial(); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } + public static com.google.protobuf.Parser parser() { + return PARSER; + } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment getDefaultInstanceForType() { + public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -9257,24 +2777,6 @@ public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_StartDeadlinesEntry_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_StartDeadlinesEntry_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_CompletedDeadlinesEntry_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_CompletedDeadlinesEntry_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_StartReassigmentsEntry_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_StartReassigmentsEntry_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_CompletedReassigmentsEntry_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_HumanTaskWorkItemData_CompletedReassigmentsEntry_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_Comment_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_Comment_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_Attachment_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_Attachment_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_Deadline_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_Deadline_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_Deadline_ContentEntry_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_Deadline_ContentEntry_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_descriptor; - private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_org_jbpm_flow_serialization_protobuf_Reassignment_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -9286,55 +2788,17 @@ public org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.Reassignment java.lang.String[] descriptorData = { "\n timer_instance_reference = 13; + optional string actual_owner = 14; + optional string external_reference_id = 15; } message LambdaSubProcessNodeInstanceContent { diff --git a/jbpm/process-serialization-protobuf/src/main/resources/org/jbpm/flow/serialization/protobuf/kogito_work_items.proto b/jbpm/process-serialization-protobuf/src/main/resources/org/jbpm/flow/serialization/protobuf/kogito_work_items.proto index 6c29fab4621..b7d2ad2f72c 100644 --- a/jbpm/process-serialization-protobuf/src/main/resources/org/jbpm/flow/serialization/protobuf/kogito_work_items.proto +++ b/jbpm/process-serialization-protobuf/src/main/resources/org/jbpm/flow/serialization/protobuf/kogito_work_items.proto @@ -38,35 +38,4 @@ message HumanTaskWorkItemData { repeated string admin_groups = 9; optional string task_reference_name = 10; - - repeated Comment comments = 11; - repeated Attachment attachments = 12; - map start_deadlines = 13; - map completed_deadlines = 14; - map start_reassigments = 15; - map completed_reassigments = 16; -} - -message Comment { - string id = 1; - optional string content = 2; - optional int64 updatedAt = 3; - optional string updatedBy = 4; -} - -message Attachment { - string id = 1; - optional string content = 2; - optional int64 updatedAt = 3; - optional string updatedBy = 4; - optional string name = 5; -} - -message Deadline { - map content = 1; } - -message Reassignment { - repeated string users = 1; - repeated string groups = 2; -} \ No newline at end of file diff --git a/jbpm/process-workitems/pom.xml b/jbpm/process-workitems/pom.xml index f3e9ead9638..a9397a4eb57 100644 --- a/jbpm/process-workitems/pom.xml +++ b/jbpm/process-workitems/pom.xml @@ -33,7 +33,7 @@ process-workitems jar - Kogito :: Process :: WorkItems + Kogito :: jBPM :: WorkItems Kogito WorkItems diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/AbstractExceptionHandlingTaskHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/AbstractExceptionHandlingTaskHandler.java similarity index 60% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/AbstractExceptionHandlingTaskHandler.java rename to jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/AbstractExceptionHandlingTaskHandler.java index 8e43264c256..0b6dd13c129 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/AbstractExceptionHandlingTaskHandler.java +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/AbstractExceptionHandlingTaskHandler.java @@ -16,14 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.handler; +package org.jbpm.process.workitem.builtin; + +import java.util.Optional; import org.kie.api.runtime.process.WorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public abstract class AbstractExceptionHandlingTaskHandler implements KogitoWorkItemHandler { +public abstract class AbstractExceptionHandlingTaskHandler extends DefaultKogitoWorkItemHandler { private KogitoWorkItemHandler originalTaskHandler; @@ -42,20 +46,12 @@ public AbstractExceptionHandlingTaskHandler(Class transitionToPhase(KogitoWorkItemManager manager, KogitoWorkItem workItem, WorkItemTransition transition) { try { - originalTaskHandler.executeWorkItem(workItem, manager); - } catch (Exception cause) { - handleExecuteException(cause, workItem, manager); - } - } - - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - try { - originalTaskHandler.abortWorkItem(workItem, manager); - } catch (RuntimeException re) { - handleAbortException(re, workItem, manager); + return this.originalTaskHandler.transitionToPhase(manager, workItem, transition); + } catch (Throwable cause) { + handleException(manager, originalTaskHandler, workItem, transition, cause); + return Optional.empty(); } } @@ -63,8 +59,6 @@ public KogitoWorkItemHandler getOriginalTaskHandler() { return originalTaskHandler; } - public abstract void handleExecuteException(Throwable cause, KogitoWorkItem workItem, KogitoWorkItemManager manager); - - public abstract void handleAbortException(Throwable cause, KogitoWorkItem workItem, KogitoWorkItemManager manager); + public abstract void handleException(KogitoWorkItemManager manager, KogitoWorkItemHandler originalTaskHandler, KogitoWorkItem workItem, WorkItemTransition transition, Throwable cause); } diff --git a/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DefaultKogitoWorkItemHandlerFactory.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DefaultKogitoWorkItemHandlerFactory.java new file mode 100644 index 00000000000..9985097bf71 --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DefaultKogitoWorkItemHandlerFactory.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.process.workitem.builtin; + +import java.util.List; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory; + +public class DefaultKogitoWorkItemHandlerFactory implements KogitoWorkItemHandlerFactory { + + @Override + public List provide() { + return List.of(new SystemOutWorkItemHandler()); + } + +} diff --git a/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DoNothingWorkItemHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DoNothingWorkItemHandler.java new file mode 100755 index 00000000000..52d5d674ca8 --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/DoNothingWorkItemHandler.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.process.workitem.builtin; + +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; + +/** + * + */ +public class DoNothingWorkItemHandler extends DefaultKogitoWorkItemHandler { + +} diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerDecorator.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/LoggingTaskHandlerDecorator.java similarity index 95% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerDecorator.java rename to jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/LoggingTaskHandlerDecorator.java index 087d09ece76..93a97daac1e 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/LoggingTaskHandlerDecorator.java +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/LoggingTaskHandlerDecorator.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.handler; +package org.jbpm.process.workitem.builtin; import java.text.MessageFormat; import java.util.ArrayDeque; @@ -28,9 +28,11 @@ import java.util.Queue; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemHandlerRuntimeException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -193,7 +195,7 @@ public synchronized List getWorkItemExceptionInfoList() { } @Override - public synchronized void handleExecuteException(Throwable cause, KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public void handleException(KogitoWorkItemManager manager, KogitoWorkItemHandler originalTaskHandler, KogitoWorkItem workItem, WorkItemTransition transition, Throwable cause) { if (exceptionInfoList.size() == this.loggedExceptionsLimit) { exceptionInfoList.poll(); } @@ -201,15 +203,6 @@ public synchronized void handleExecuteException(Throwable cause, KogitoWorkItem logMessage(true, workItem, cause); } - @Override - public synchronized void handleAbortException(Throwable cause, KogitoWorkItem workItem, KogitoWorkItemManager manager) { - if (exceptionInfoList.size() == this.loggedExceptionsLimit) { - exceptionInfoList.poll(); - } - exceptionInfoList.add(new WorkItemExceptionInfo(workItem, cause, false)); - logMessage(false, workItem, cause); - } - public static void setLogger(Logger logger) { LoggingTaskHandlerDecorator.logger = logger; } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/MockDataWorkItemHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/MockDataWorkItemHandler.java similarity index 69% rename from jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/MockDataWorkItemHandler.java rename to jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/MockDataWorkItemHandler.java index 52d6b248678..a9997db648d 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/demo/MockDataWorkItemHandler.java +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/MockDataWorkItemHandler.java @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.process.instance.impl.demo; +package org.jbpm.process.workitem.builtin; import java.util.Map; +import java.util.Optional; import java.util.function.Function; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; /** * Simple work item handler that allows to provide output data or supplier @@ -31,7 +34,7 @@ * of provided input data. * */ -public class MockDataWorkItemHandler implements KogitoWorkItemHandler { +public class MockDataWorkItemHandler extends DefaultKogitoWorkItemHandler { private Function, Map> outputDataSupplier; /** @@ -54,12 +57,8 @@ public MockDataWorkItemHandler(Function, Map } @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.completeWorkItem(workItem.getStringId(), outputDataSupplier.apply(workItem.getParameters())); - } - - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), outputDataSupplier.apply(workItem.getParameters()))); } } diff --git a/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ReceiveTaskHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ReceiveTaskHandler.java new file mode 100755 index 00000000000..d18a80b8b1a --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ReceiveTaskHandler.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.process.workitem.builtin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; + +public class ReceiveTaskHandler extends DefaultKogitoWorkItemHandler { + + private Map waiting = new HashMap<>(); + + public Collection getWorkItemId() { + return new ArrayList<>(waiting.values()); + } + + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + String messageId = (String) workItem.getParameter("MessageId"); + waiting.put(messageId, workItem.getStringId()); + return Optional.empty(); + } + + @Override + public Optional completeWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + String messageId = (String) workItem.getParameter("MessageId"); + waiting.remove(messageId); + return Optional.empty(); + } + + @Override + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + String messageId = (String) workItem.getParameter("MessageId"); + waiting.remove(messageId); + return Optional.empty(); + } + +} diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/SendTaskHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SendTaskHandler.java similarity index 56% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/SendTaskHandler.java rename to jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SendTaskHandler.java index a473a69c359..2a17a585cf5 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/SendTaskHandler.java +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SendTaskHandler.java @@ -16,25 +16,28 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.handler; +package org.jbpm.process.workitem.builtin; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import java.util.Collections; +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SendTaskHandler implements KogitoWorkItemHandler { +public class SendTaskHandler extends DefaultKogitoWorkItemHandler { private static final Logger logger = LoggerFactory.getLogger(SendTaskHandler.class); - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { String message = (String) workItem.getParameter("Message"); logger.debug("Sending message: {}", message); - manager.completeWorkItem(workItem.getStringId(), null); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), Collections.emptyMap())); } - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - // Do nothing, cannot be aborted - } } diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ServiceTaskHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ServiceTaskHandler.java similarity index 81% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ServiceTaskHandler.java rename to jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ServiceTaskHandler.java index 854b912db72..9dd9e7098a5 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ServiceTaskHandler.java +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/ServiceTaskHandler.java @@ -16,20 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.handler; +package org.jbpm.process.workitem.builtin; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.Optional; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemHandlerRuntimeException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ServiceTaskHandler implements KogitoWorkItemHandler { +public class ServiceTaskHandler extends DefaultKogitoWorkItemHandler { private static final Logger logger = LoggerFactory.getLogger(ServiceTaskHandler.class); @@ -43,7 +47,9 @@ public ServiceTaskHandler(String resultVarName) { this.resultVarName = resultVarName; } - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + String service = (String) workItem.getParameter("Interface"); String interfaceImplementationRef = (String) workItem.getParameter("interfaceImplementationRef"); String operation = (String) workItem.getParameter("Operation"); @@ -80,10 +86,12 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manag Object result = method.invoke(instance, params); Map results = new HashMap<>(); results.put(resultVarName, result); - manager.completeWorkItem(workItem.getStringId(), results); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), results)); } catch (Exception cnfe) { handleException(cnfe, service, interfaceImplementationRef, operation, parameterType, parameter); + return Optional.empty(); } + } private void handleException(Throwable cause, String service, String interfaceImplementationRef, String operation, String paramType, Object param) { @@ -103,7 +111,4 @@ private void handleException(Throwable cause, String service, String interfaceIm throw wihRe; } - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - // Do nothing, cannot be aborted - } } diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/SignallingTaskHandlerDecorator.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SignallingTaskHandlerDecorator.java similarity index 70% rename from jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/SignallingTaskHandlerDecorator.java rename to jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SignallingTaskHandlerDecorator.java index 7acf0a320b0..27cd7cfd602 100755 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/SignallingTaskHandlerDecorator.java +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SignallingTaskHandlerDecorator.java @@ -16,14 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jbpm.bpmn2.handler; +package org.jbpm.process.workitem.builtin; import java.util.HashMap; import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemHandlerRuntimeException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; /** @@ -91,26 +93,31 @@ public String getWorkItemExceptionParameterName() { } @Override - public void handleExecuteException(Throwable cause, org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem, org.kie.kogito.internal.process.runtime.KogitoWorkItemManager manager) { - if (getAndIncreaseExceptionCount(workItem.getProcessInstanceStringId()) < exceptionCountLimit) { - workItem.getParameters().put(this.workItemExceptionParameterName, cause); - ((InternalKogitoWorkItemManager) manager).signalEvent(this.eventType, workItem, workItem.getProcessInstanceStringId()); - } else { - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } else { - throw new WorkItemHandlerRuntimeException(cause, - "Signalling process instance " + workItem.getProcessInstanceId() + " with '" + this.eventType + "' resulted this exception."); + public void handleException(KogitoWorkItemManager manager, KogitoWorkItemHandler originalTaskHandler, KogitoWorkItem workItem, WorkItemTransition transition, Throwable cause) { + switch (transition.id()) { + case "activate": { + if (getAndIncreaseExceptionCount(workItem.getProcessInstanceStringId()) < exceptionCountLimit) { + workItem.getParameters().put(this.workItemExceptionParameterName, cause); + ((InternalKogitoWorkItemManager) manager).signalEvent(this.eventType, workItem, workItem.getProcessInstanceStringId()); + } else { + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else { + throw new WorkItemHandlerRuntimeException(cause, + "Signalling process instance " + workItem.getProcessInstanceId() + " with '" + this.eventType + "' resulted this exception."); + } + } + break; + } + case "abort": { + if (getAndIncreaseExceptionCount(workItem.getProcessInstanceStringId()) < exceptionCountLimit) { + workItem.getParameters().put(this.workItemExceptionParameterName, cause); + ((InternalKogitoWorkItemManager) manager).signalEvent(this.eventType, workItem, workItem.getProcessInstanceId()); + } + break; } } - } - @Override - public void handleAbortException(Throwable cause, org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem, org.kie.kogito.internal.process.runtime.KogitoWorkItemManager manager) { - if (getAndIncreaseExceptionCount(workItem.getProcessInstanceStringId()) < exceptionCountLimit) { - workItem.getParameters().put(this.workItemExceptionParameterName, cause); - ((InternalKogitoWorkItemManager) manager).signalEvent(this.eventType, workItem, workItem.getProcessInstanceId()); - } } private int getAndIncreaseExceptionCount(String processInstanceId) { @@ -126,10 +133,6 @@ public void setExceptionCountLimit(int limit) { this.exceptionCountLimit = limit; } - public void clearProcessInstance(Long processInstanceId) { - processInstanceExceptionMap.remove(processInstanceId); - } - public void clear() { processInstanceExceptionMap.clear(); } diff --git a/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SystemOutWorkItemHandler.java b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SystemOutWorkItemHandler.java new file mode 100755 index 00000000000..8a885a3c815 --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/jbpm/process/workitem/builtin/SystemOutWorkItemHandler.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.process.workitem.builtin; + +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; + +public class SystemOutWorkItemHandler extends DefaultKogitoWorkItemHandler { + + @Override + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + System.out.println("Executing work item " + workItem); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), workItem.getResults())); + } + + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + System.out.println("Aborting work item " + workItem); + return Optional.of(this.workItemLifeCycle.newTransition("abort", workItem.getPhaseStatus(), workItem.getResults())); + } + + @Override + public String getName() { + return "Log"; + } +} diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItem.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItem.java index e1bbb25614e..c6a51b9c7a7 100755 --- a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItem.java +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItem.java @@ -23,7 +23,11 @@ import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -public interface InternalKogitoWorkItem extends org.drools.core.process.WorkItem, org.kie.kogito.internal.process.runtime.KogitoWorkItem { +public interface InternalKogitoWorkItem extends org.drools.core.process.WorkItem, org.kie.kogito.internal.process.workitem.KogitoWorkItem { + + void setExternalReferenceId(String id); + + void setActualOwner(String owner); void setProcessInstanceId(String processInstanceId); @@ -43,7 +47,5 @@ public interface InternalKogitoWorkItem extends org.drools.core.process.WorkItem void setProcessInstance(KogitoProcessInstance processInstance); - void setResult(String name, Object value); - void setId(String string); } diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItemManager.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItemManager.java index b3e9e081a16..845aeaff884 100755 --- a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItemManager.java +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/InternalKogitoWorkItemManager.java @@ -22,9 +22,9 @@ import java.util.Set; import org.kie.api.runtime.process.WorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; -public interface InternalKogitoWorkItemManager extends org.drools.core.process.WorkItemManager, org.kie.kogito.internal.process.runtime.KogitoWorkItemManager { +public interface InternalKogitoWorkItemManager extends org.drools.core.process.WorkItemManager, org.kie.kogito.internal.process.workitem.KogitoWorkItemManager { void internalExecuteWorkItem(InternalKogitoWorkItem workItem); diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultKogitoWorkItemHandler.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultKogitoWorkItemHandler.java new file mode 100644 index 00000000000..993fb8f8ade --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultKogitoWorkItemHandler.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.process.workitems.impl; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.kie.kogito.Application; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCycle; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCyclePhase; +import org.kie.kogito.internal.process.workitem.WorkItemPhaseState; +import org.kie.kogito.internal.process.workitem.WorkItemTerminationType; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.util.Collections.emptyMap; +import static java.util.stream.Collectors.toSet; + +public class DefaultKogitoWorkItemHandler implements KogitoWorkItemHandler { + + public static final String TRANSITION_COMPLETE = "complete"; + public static final String TRANSITION_ABORT = "abort"; + public static final String TRANSITION_ACTIVATE = "activate"; + public static final String TRANSITION_SKIP = "skip"; + + private static Logger LOG = LoggerFactory.getLogger(DefaultKogitoWorkItemHandler.class); + + protected Application application; + + protected WorkItemLifeCycle workItemLifeCycle; + + public DefaultKogitoWorkItemHandler(WorkItemLifeCycle workItemLifeCycle) { + this.workItemLifeCycle = workItemLifeCycle; + } + + public DefaultKogitoWorkItemHandler() { + this.workItemLifeCycle = initialize(); + } + + public WorkItemLifeCycle initialize() { + WorkItemPhaseState initialized = WorkItemPhaseState.initialized(); + WorkItemPhaseState completed = WorkItemPhaseState.of("Completed", WorkItemTerminationType.COMPLETE); + WorkItemPhaseState aborted = WorkItemPhaseState.of("Aborted", WorkItemTerminationType.ABORT); + WorkItemPhaseState activated = WorkItemPhaseState.of("Activated"); + + DefaultWorkItemLifeCyclePhase complete = new DefaultWorkItemLifeCyclePhase(TRANSITION_COMPLETE, activated, completed, this::completeWorkItemHandler); + DefaultWorkItemLifeCyclePhase abort = new DefaultWorkItemLifeCyclePhase(TRANSITION_ABORT, activated, aborted, this::abortWorkItemHandler); + DefaultWorkItemLifeCyclePhase active = new DefaultWorkItemLifeCyclePhase(TRANSITION_ACTIVATE, initialized, activated, this::activateWorkItemHandler); + DefaultWorkItemLifeCyclePhase skip = new DefaultWorkItemLifeCyclePhase(TRANSITION_SKIP, activated, completed, this::skipWorkItemHandler); + return new DefaultWorkItemLifeCycle(active, skip, abort, complete); + } + + public void setApplication(Application application) { + this.application = application; + } + + @Override + public Application getApplication() { + return this.application; + } + + @Override + public WorkItemTransition startingTransition(Map data, Policy... policies) { + return workItemLifeCycle.newTransition("activate", null, data, policies); + } + + @Override + public WorkItemTransition abortTransition(String phaseStatus, Policy... policies) { + return workItemLifeCycle.newTransition("abort", phaseStatus, emptyMap(), policies); + } + + @Override + public WorkItemTransition completeTransition(String phaseStatus, Map data, Policy... policies) { + return workItemLifeCycle.newTransition("complete", phaseStatus, data, policies); + } + + @Override + public Optional transitionToPhase(KogitoWorkItemManager manager, KogitoWorkItem workItem, WorkItemTransition transition) { + LOG.debug("workItem {} handled by {} transition {}", workItem, this.getName(), transition); + try { + return workItemLifeCycle.transitionTo(manager, this, workItem, transition); + } catch (RuntimeException e) { + LOG.info("error workItem {} handled by {} transition {} ", workItem, this.getName(), transition, e); + throw e; + } + } + + @Override + public Set allowedTransitions(String phaseStatus) { + return workItemLifeCycle.allowedPhases(phaseStatus).stream().map(WorkItemLifeCyclePhase::id).collect(toSet()); + } + + @Override + public WorkItemTransition newTransition(String phaseId, String phaseStatus, Map map, Policy... policy) { + return workItemLifeCycle.newTransition(phaseId, phaseStatus, map, policy); + } + + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return Optional.empty(); + } + + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return Optional.empty(); + } + + public Optional completeWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return Optional.empty(); + } + + public Optional skipWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return Optional.empty(); + } +} diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCycle.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCycle.java new file mode 100644 index 00000000000..64fc2a8a2e8 --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCycle.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.process.workitems.impl; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCycle; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCyclePhase; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; + +public class DefaultWorkItemLifeCycle implements WorkItemLifeCycle { + + List phases; + + public DefaultWorkItemLifeCycle(WorkItemLifeCyclePhase... phases) { + this.phases = List.of(phases); + } + + @Override + public Optional transitionTo(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + WorkItemLifeCyclePhase phase = phaseById(transition.id(), workItem.getPhaseStatus()); + if (phase == null) { + throw new InvalidTransitionException("transition id " + transition.id() + " is not allowed for handler " + workItem.getName() + " from " + workItem.getPhaseStatus()); + } + transition.policies().stream().forEach(policy -> policy.enforce(workItem)); + if (workItem instanceof KogitoWorkItemImpl impl) { + impl.setPhaseId(phase.id()); + impl.setPhaseStatus(phase.targetStatus().getName()); + impl.setResults((Map) transition.data()); + } + + return phase.execute(manager, handler, workItem, transition); + } + + @Override + public Collection phases() { + return phases; + } + + @Override + public WorkItemTransition newTransition(String transitionId, String currentPhaseStatus, Map data, Policy... policy) { + WorkItemLifeCyclePhase phase = phaseById(transitionId, currentPhaseStatus); + if (phase == null) { + throw new InvalidTransitionException("new transition id " + transitionId + " is not allowed from " + currentPhaseStatus + " is invalid"); + } + return new DefaultWorkItemTransitionImpl(transitionId, phase.targetStatus().getTermination().orElse(null), data, policy); + } + +} diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCyclePhase.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCyclePhase.java new file mode 100644 index 00000000000..7e2163a6125 --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemLifeCyclePhase.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.process.workitems.impl; + +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemLifeCyclePhase; +import org.kie.kogito.internal.process.workitem.WorkItemPhaseState; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; + +public class DefaultWorkItemLifeCyclePhase implements WorkItemLifeCyclePhase { + + public interface WorkItemLifeCyclePhaseExecutor { + Optional execute(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition); + } + + private String id; + private WorkItemPhaseState sourceStatus; + private WorkItemPhaseState targetStatus; + private WorkItemLifeCyclePhaseExecutor execution; + + public DefaultWorkItemLifeCyclePhase(String id, WorkItemPhaseState sourceStatus, WorkItemPhaseState targetStatus, WorkItemLifeCyclePhaseExecutor execution) { + this.id = id; + this.sourceStatus = sourceStatus; + this.targetStatus = targetStatus; + this.execution = execution; + } + + @Override + public String id() { + return id; + } + + @Override + public WorkItemPhaseState sourceStatus() { + return sourceStatus; + } + + @Override + public WorkItemPhaseState targetStatus() { + return targetStatus; + } + + @Override + public Optional execute(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return this.execution.execute(manager, handler, workitem, transition); + } + + @Override + public boolean isStartingPhase() { + return sourceStatus != null; + } + + @Override + public String toString() { + return "DefaultWorkItemLifeCyclePhase[transition=" + id + ", oldStatus=" + sourceStatus + ", newStatus=" + targetStatus + ", isStarting=" + isStartingPhase() + "]"; + } + +} diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemTransitionImpl.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemTransitionImpl.java new file mode 100644 index 00000000000..8ce4f36468e --- /dev/null +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/DefaultWorkItemTransitionImpl.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.process.workitems.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemTerminationType; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; + +public class DefaultWorkItemTransitionImpl implements WorkItemTransition { + + private String id; + private Map data; + private List policies; + private WorkItemTerminationType termination; + + public DefaultWorkItemTransitionImpl(String id, WorkItemTerminationType termination, Map data, Policy... policies) { + this.id = id; + this.data = new HashMap<>(); + this.policies = List.of(policies); + this.termination = termination; + if (data != null) { + this.data.putAll(data); + } + } + + @Override + public String id() { + return id; + } + + @Override + public Map data() { + return data; + } + + @Override + public List policies() { + return policies; + } + + public void setTermination(WorkItemTerminationType termination) { + this.termination = termination; + } + + @Override + public Optional termination() { + return Optional.ofNullable(this.termination); + } + + @Override + public String toString() { + return "DefaultWorkItemTransitionImpl [id=" + id + ", data=" + data + ", policies=" + policies + ", termination=" + termination + "]"; + } + +} diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoDefaultWorkItemManager.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoDefaultWorkItemManager.java index 46635608971..55304c9a2bc 100755 --- a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoDefaultWorkItemManager.java +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoDefaultWorkItemManager.java @@ -18,171 +18,199 @@ */ package org.kie.kogito.process.workitems.impl; -import java.io.IOException; -import java.io.ObjectOutput; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.drools.core.process.WorkItem; import org.kie.internal.runtime.Closeable; -import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerNotFoundException; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.workitems.InternalKogitoWorkItem; import org.kie.kogito.process.workitems.InternalKogitoWorkItemManager; -import org.kie.kogito.process.workitems.KogitoWorkItemHandlerNotFoundException; -import static org.kie.api.runtime.process.WorkItem.ABORTED; -import static org.kie.api.runtime.process.WorkItem.COMPLETED; +import static java.util.Collections.emptyMap; public class KogitoDefaultWorkItemManager implements InternalKogitoWorkItemManager { - - private Map workItems = new ConcurrentHashMap<>(); + private Map workItems; + private Map workItemHandlers; private KogitoProcessRuntime kruntime; - private Map workItemHandlers = new HashMap<>(); public KogitoDefaultWorkItemManager(KogitoProcessRuntime kruntime) { this.kruntime = kruntime; - } - - public void writeExternal(ObjectOutput out) throws IOException { - out.writeObject(workItems); - out.writeObject(kruntime); - out.writeObject(workItemHandlers); + this.workItems = new ConcurrentHashMap<>(); + this.workItemHandlers = new HashMap<>(); } @Override - public void internalExecuteWorkItem(InternalKogitoWorkItem workItem) { - internalAddWorkItem(workItem); - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - handler.executeWorkItem(workItem, this); - } else - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + public void clear() { + this.workItems.clear(); } @Override - public void internalAddWorkItem(InternalKogitoWorkItem workItem) { - workItems.put(workItem.getStringId(), workItem); + public void signalEvent(String type, Object event) { + this.kruntime.signalEvent(type, event); } @Override - public void internalRemoveWorkItem(String id) { - workItems.remove(id); + public void dispose() { + if (workItemHandlers != null) { + for (Map.Entry handlerEntry : workItemHandlers.entrySet()) { + if (handlerEntry.getValue() instanceof Closeable) { + ((Closeable) handlerEntry.getValue()).close(); + } + } + } } @Override - public void internalAbortWorkItem(String id) { - InternalKogitoWorkItem workItem = workItems.get(id); - // work item may have been aborted - if (workItem != null) { - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - handler.abortWorkItem(workItem, this); - } else { - workItems.remove(workItem.getStringId()); - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); - } - workItems.remove(workItem.getStringId()); + public T updateWorkItem(String id, Function updater, Policy... policies) { + KogitoWorkItem workItem = workItems.get(id); + if (workItem == null) { + throw new WorkItemNotFoundException(id); } + + Stream.of(policies).forEach(p -> p.enforce(workItem)); + return updater.apply(workItem); + } - public void retryWorkItem(String workItemId) { - InternalKogitoWorkItem workItem = workItems.get(workItemId); - retryWorkItem(workItem); + @Override + public Collection getHandlerIds() { + return this.workItemHandlers.keySet(); } - public void retryWorkItemWithParams(String workItemId, Map map) { - InternalKogitoWorkItem workItem = workItems.get(workItemId); + @Override + public KogitoWorkItemHandler getKogitoWorkItemHandler(String name) { + return this.workItemHandlers.get(name); + } - if (workItem != null) { - workItem.setParameters(map); + @Override + public void registerWorkItemHandler(String workItemName, KogitoWorkItemHandler handler) { + this.workItemHandlers.put(workItemName, handler); + } - retryWorkItem(workItem); + @Override + public void transitionWorkItem(String id, WorkItemTransition transition) { + InternalKogitoWorkItem workItem = getWorkItem(id); + if (workItem == null) { + throw new WorkItemNotFoundException(id); } + transitionWorkItem(workItem, transition, true); } - private void retryWorkItem(InternalKogitoWorkItem workItem) { - if (workItem != null) { - KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); - if (handler != null) { - handler.executeWorkItem(workItem, this); - } else - throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + public void transitionWorkItem(InternalKogitoWorkItem workItem, WorkItemTransition transition, boolean signal) { + + KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); + if (handler == null) { + throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + } + WorkItemTransition lastTransition = null; + Optional nextTransition = Optional.of(transition); + while (nextTransition.isPresent()) { + lastTransition = nextTransition.get(); + nextTransition = handler.transitionToPhase(this, workItem, nextTransition.get()); + this.kruntime.getProcessEventSupport().fireBeforeWorkItemTransition(workItem.getProcessInstance(), workItem, lastTransition, this.kruntime.getKieRuntime()); + workItem.getProcessInstance().signalEvent("workItemTransition", transition); + this.kruntime.getProcessEventSupport().fireAfterWorkItemTransition(workItem.getProcessInstance(), workItem, lastTransition, this.kruntime.getKieRuntime()); } + + if (lastTransition.termination().isPresent()) { + internalRemoveWorkItem(workItem.getStringId()); + if (signal) { + switch (lastTransition.termination().get()) { + case COMPLETE: + workItem.setState(KogitoWorkItem.COMPLETED); + workItem.getProcessInstance().signalEvent("workItemCompleted", workItem); + break; + case ABORT: + workItem.setState(KogitoWorkItem.ABORTED); + workItem.getProcessInstance().signalEvent("workItemAborted", workItem); + break; + } + } + } + } @Override - public InternalKogitoWorkItem getWorkItem(String id) { - return workItems.get(id); + public void internalAddWorkItem(InternalKogitoWorkItem workItem) { + workItems.put(workItem.getStringId(), workItem); } @Override - public void completeWorkItem(String id, Map results, Policy... policies) { - InternalKogitoWorkItem workItem = workItems.get(id); - // work item may have been aborted - if (workItem != null) { - workItem.setResults(results); - KogitoProcessInstance processInstance = kruntime.getProcessInstance(workItem.getProcessInstanceStringId()); - workItem.setState(COMPLETED); - // process instance may have finished already - if (processInstance != null) { - processInstance.signalEvent("workItemCompleted", workItem); - } - workItems.remove(id); - } + public void abortWorkItem(String id, Policy... policies) { + InternalKogitoWorkItem workItem = getWorkItem(id); + Stream.of(policies).forEach(p -> p.enforce(workItem)); + internalAbortWorkItem(workItem.getStringId()); + workItem.setState(KogitoWorkItem.ABORTED); + this.kruntime.signalEvent("workItemAborted", workItem, workItem.getProcessInstanceId()); } @Override - public void abortWorkItem(String id, Policy... policies) { - InternalKogitoWorkItem workItem = workItems.get(id); - // work item may have been aborted - if (workItem != null) { - KogitoProcessInstance processInstance = kruntime.getProcessInstance(workItem.getProcessInstanceStringId()); - workItem.setState(ABORTED); - // process instance may have finished already - if (processInstance != null) { - processInstance.signalEvent("workItemAborted", workItem); - } - workItems.remove(id); + public void internalAbortWorkItem(String id) { + InternalKogitoWorkItem workItem = getWorkItem(id); + KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); + if (handler == null) { + throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); } + WorkItemTransition transition = handler.abortTransition(workItem.getPhaseStatus()); + transitionWorkItem(workItem, transition, false); } @Override - public void completeWorkItem(long l, Map map) { - throw new UnsupportedOperationException(); + public void completeWorkItem(String id, Map results, Policy... policies) { + InternalKogitoWorkItem workItem = getWorkItem(id); + Stream.of(policies).forEach(p -> p.enforce(workItem)); + workItem.setResults(results != null ? results : emptyMap()); + internalCompleteWorkItem(workItem); + workItem.setState(KogitoWorkItem.COMPLETED); + this.kruntime.signalEvent("workItemCompleted", workItem, workItem.getProcessInstanceId()); } @Override - public void abortWorkItem(long l) { - throw new UnsupportedOperationException(); + public void internalCompleteWorkItem(InternalKogitoWorkItem workItem) { + KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); + if (handler == null) { + throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + } + WorkItemTransition transition = handler.completeTransition(workItem.getPhaseStatus(), workItem.getResults()); + transitionWorkItem(workItem, transition, false); + internalRemoveWorkItem(workItem.getStringId()); } @Override - public Set getWorkItems() { - return new HashSet<>(workItems.values()); - } + public void internalExecuteWorkItem(InternalKogitoWorkItem workItem) { + internalAddWorkItem(workItem); + KogitoWorkItemHandler handler = this.workItemHandlers.get(workItem.getName()); + if (handler == null) { + throw new KogitoWorkItemHandlerNotFoundException(workItem.getName()); + } + WorkItemTransition transition = handler.startingTransition(Collections.emptyMap()); + transitionWorkItem(workItem, transition, true); - @Override - public void registerWorkItemHandler(String workItemName, KogitoWorkItemHandler handler) { - this.workItemHandlers.put(workItemName, handler); } @Override - public void clear() { - this.workItems.clear(); + public InternalKogitoWorkItem getWorkItem(String id) { + return workItems.get(id); } @Override - public void signalEvent(String type, Object event) { - this.kruntime.signalEvent(type, event); + public void internalRemoveWorkItem(String id) { + workItems.remove(id); } @Override @@ -191,42 +219,33 @@ public void signalEvent(String type, Object event, String processInstanceId) { } @Override - public void dispose() { - if (workItemHandlers != null) { - for (Map.Entry handlerEntry : workItemHandlers.entrySet()) { - if (handlerEntry.getValue() instanceof Closeable) { - ((Closeable) handlerEntry.getValue()).close(); - } - } - } + public void retryWorkItem(String workItemId, Map params) { + Map normalizedParams = params != null && params.isEmpty() ? Collections.emptyMap() : params; + this.retryWorkItemWithParams(workItemId, normalizedParams); + } + + public void retryWorkItemWithParams(String workItemId, Map map) { + InternalKogitoWorkItem workItem = workItems.get(workItemId); + workItem.setPhaseId(null); + workItem.setPhaseStatus(null); + workItem.setParameters(map); + internalExecuteWorkItem(workItem); } @Override - public void retryWorkItem(String workItemID, Map params) { - if (params == null || params.isEmpty()) { - retryWorkItem(workItemID); - } else { - this.retryWorkItemWithParams(workItemID, params); - } + public Set getWorkItems() { + return workItems.values().stream().collect(Collectors.toSet()); } @Override - public void internalCompleteWorkItem(InternalKogitoWorkItem workItem) { + public void completeWorkItem(long id, Map results) { + throw new UnsupportedOperationException(); } @Override - public T updateWorkItem(String id, - Function updater, - Policy... policies) { - KogitoWorkItem workItem = workItems.get(id); - if (workItem != null) { - if (!workItem.enforce(policies)) { - throw new NotAuthorizedException("User is not authorized to access task instance with id " + id); - } - return updater.apply(workItem); - } else { - throw new WorkItemNotFoundException(id); - } + public void abortWorkItem(long id) { + throw new UnsupportedOperationException(); } + } diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java index dea6844d075..af061463843 100755 --- a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java @@ -55,6 +55,9 @@ public class KogitoWorkItemImpl implements InternalKogitoWorkItem, Serializable private transient KogitoProcessInstance processInstance; private transient KogitoNodeInstance nodeInstance; + private String externalReferenceId; + private String actualOwner; + public void setId(String id) { this.id = id; } @@ -112,12 +115,13 @@ public Map getParameters() { @Override public void setResults(Map results) { if (results != null) { - this.results = results; + this.results.clear(); + this.results.putAll(results); } } @Override - public void setResult(String name, Object value) { + public void setOutput(String name, Object value) { results.put(name, value); } @@ -226,6 +230,11 @@ public void setCompleteDate(Date completeDate) { this.completeDate = completeDate; } + @Override + public void removeOutput(String name) { + this.results.remove(name); + } + @Override public String toString() { StringBuilder b = new StringBuilder("WorkItem "); @@ -527,4 +536,23 @@ private Object processValue(T obj) { return obj instanceof WorkItemParamResolver ? ((WorkItemParamResolver) obj).apply(this) : obj; } + @Override + public String getExternalReferenceId() { + return externalReferenceId; + } + + @Override + public void setExternalReferenceId(String externalReferenceId) { + this.externalReferenceId = externalReferenceId; + } + + @Override + public String getActualOwner() { + return this.actualOwner; + } + + @Override + public void setActualOwner(String actualOwner) { + this.actualOwner = actualOwner; + } } diff --git a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/WorkItemParamResolver.java b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/WorkItemParamResolver.java index 2851af39e45..42e8b2032af 100644 --- a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/WorkItemParamResolver.java +++ b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/WorkItemParamResolver.java @@ -20,7 +20,7 @@ import java.util.function.Function; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; /* Added to make it easier to search for ParamResolver function implementations, * see https://github.com/kiegroup/kogito-runtimes/pull/778#pullrequestreview-493382982 */ diff --git a/jbpm/process-workitems/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory b/jbpm/process-workitems/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory new file mode 100644 index 00000000000..405516ab881 --- /dev/null +++ b/jbpm/process-workitems/src/main/resources/META-INF/services/org.kie.kogito.internal.process.workitem.KogitoWorkItemHandlerFactory @@ -0,0 +1 @@ +org.jbpm.process.workitem.builtin.DefaultKogitoWorkItemHandlerFactory \ No newline at end of file diff --git a/jbpm/process-workitems/src/test/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImplTest.java b/jbpm/process-workitems/src/test/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImplTest.java index 0958e25113f..9b295e3ddae 100644 --- a/jbpm/process-workitems/src/test/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImplTest.java +++ b/jbpm/process-workitems/src/test/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImplTest.java @@ -22,7 +22,7 @@ import java.util.Map; import org.junit.jupiter.api.Test; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import static org.assertj.core.api.Assertions.assertThat; diff --git a/kogito-bom/pom.xml b/kogito-bom/pom.xml index a8ac56322d1..41d7037eb35 100755 --- a/kogito-bom/pom.xml +++ b/kogito-bom/pom.xml @@ -1845,6 +1845,11 @@ jbpm-flow-migration ${project.version} + + org.kie.kogito + jbpm-usertask + ${project.version} + org.kie.kogito jbpm-flow-migration diff --git a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/template/TemplatedGenerator.java b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/template/TemplatedGenerator.java index 4d57d572457..0c377046d81 100644 --- a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/template/TemplatedGenerator.java +++ b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/template/TemplatedGenerator.java @@ -146,7 +146,12 @@ public String uncheckedTemplatePath() { } private InputStream getResource(String path) { - return this.getClass().getResourceAsStream(path); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + InputStream is = classLoader.getResourceAsStream(path); + if (is == null) { + return this.getClass().getResourceAsStream(path); + } + return is; } public static Builder builder() { diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/ApplicationGeneratorDiscovery.java b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/ApplicationGeneratorDiscovery.java index 7d1f8dd2e68..183d11b7b03 100644 --- a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/ApplicationGeneratorDiscovery.java +++ b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/ApplicationGeneratorDiscovery.java @@ -47,17 +47,14 @@ private ApplicationGeneratorDiscovery() { public static ApplicationGenerator discover(KogitoBuildContext context) { ApplicationGenerator appGen = new ApplicationGenerator(context); - - loadGenerators(context) - .forEach(appGen::registerGeneratorIfEnabled); - + loadGenerators(context).forEach(appGen::registerGeneratorIfEnabled); return appGen; } protected static Collection loadGenerators(KogitoBuildContext context) { Collection collectedResources = CollectedResourceProducer.fromPaths(context.ignoreHiddenFiles(), context.getAppPaths().getPaths()); - ServiceLoader generatorFactories = ServiceLoader.load(GeneratorFactory.class); + ServiceLoader generatorFactories = ServiceLoader.load(GeneratorFactory.class, context.getClassLoader()); List generators = StreamSupport.stream(generatorFactories.spliterator(), false) .map(gf -> gf.create(context, collectedResources)) diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java index 3a94082488f..a09388af452 100644 --- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java +++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java @@ -36,6 +36,8 @@ import org.drools.codegen.common.GeneratedFile; import org.drools.compiler.compiler.io.memory.MemoryFileSystem; import org.drools.util.PortablePath; +import org.jbpm.process.instance.LightWorkItemManager; +import org.junit.platform.commons.util.ClassLoaderUtils; import org.kie.kogito.Application; import org.kie.kogito.codegen.api.AddonsConfig; import org.kie.kogito.codegen.api.Generator; @@ -45,6 +47,11 @@ import org.kie.kogito.codegen.core.ApplicationGenerator; import org.kie.kogito.codegen.core.io.CollectedResourceProducer; import org.kie.kogito.codegen.process.ProcessCodegen; +import org.kie.kogito.codegen.usertask.UserTaskCodegen; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.WorkItem; +import org.kie.kogito.process.impl.AbstractProcess; import org.kie.memorycompiler.CompilationResult; import org.kie.memorycompiler.JavaCompiler; import org.kie.memorycompiler.JavaCompilerFactory; @@ -64,6 +71,7 @@ public abstract class AbstractCodegenIT { * {@link ApplicationGenerator#registerGeneratorIfEnabled(Generator) } */ protected enum TYPE { + USER_TASK, PROCESS, RULES, DECISION, @@ -116,6 +124,7 @@ protected enum TYPE { static { generatorTypeMap.put(TYPE.PROCESS, (context, strings) -> ProcessCodegen.ofCollectedResources(context, toCollectedResources(TEST_RESOURCES, strings))); + generatorTypeMap.put(TYPE.USER_TASK, (context, strings) -> UserTaskCodegen.ofCollectedResources(context, toCollectedResources(TEST_RESOURCES, strings))); } public static Collection toCollectedResources(String basePath, List strings) { @@ -133,6 +142,7 @@ public static Collection toCollectedResources(List st protected Application generateCodeProcessesOnly(String... processes) throws Exception { Map> resourcesTypeMap = new HashMap<>(); resourcesTypeMap.put(TYPE.PROCESS, Arrays.asList(processes)); + resourcesTypeMap.put(TYPE.USER_TASK, Arrays.asList(processes)); return generateCode(resourcesTypeMap); } @@ -165,14 +175,14 @@ protected Application generateCode(Map> resourcesTypeMap, Kog log(new String(entry.contents())); } - if (resourcesTypeMap.size() == 1 && resourcesTypeMap.containsKey(TYPE.PROCESS)) { + if (!resourcesTypeMap.isEmpty() && resourcesTypeMap.containsKey(TYPE.PROCESS) && !resourcesTypeMap.containsKey(TYPE.RULES)) { sources.add("org/drools/project/model/ProjectRuntime.java"); srcMfs.write("org/drools/project/model/ProjectRuntime.java", DUMMY_PROCESS_RUNTIME.getBytes()); } - if (LOGGER.isDebugEnabled()) { + if (LOGGER.isInfoEnabled()) { Path temp = Files.createTempDirectory("KOGITO_TESTS"); - LOGGER.debug("Dumping generated files in " + temp); + LOGGER.info("Dumping generated files in " + temp); for (GeneratedFile entry : generatedFiles) { Path fpath = temp.resolve(entry.relativePath()); fpath.getParent().toFile().mkdirs(); @@ -180,7 +190,7 @@ protected Application generateCode(Map> resourcesTypeMap, Kog } } - CompilationResult result = JAVA_COMPILER.compile(sources.toArray(new String[sources.size()]), srcMfs, trgMfs, this.getClass().getClassLoader()); + CompilationResult result = JAVA_COMPILER.compile(sources.toArray(new String[sources.size()]), srcMfs, trgMfs, ClassLoaderUtils.getDefaultClassLoader()); assertThat(result).isNotNull(); assertThat(result.getErrors()).describedAs(String.join("\n\n", Arrays.toString(result.getErrors()))).isEmpty(); @@ -240,4 +250,8 @@ protected Class findClass(final String name) throws ClassNotFoundException { return super.findClass(name); } } + + protected KogitoWorkItemHandler getWorkItemHandler(Process p, WorkItem workItem) { + return ((LightWorkItemManager) ((AbstractProcess) p).getProcessRuntime().getKogitoWorkItemManager()).getWorkItemHandler(workItem.getId()); + } } diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/CallActivityTaskIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/CallActivityTaskIT.java index 661d6d0263f..372f770c88e 100644 --- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/CallActivityTaskIT.java +++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/CallActivityTaskIT.java @@ -19,33 +19,33 @@ package org.kie.kogito.codegen.tests; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.jbpm.process.instance.impl.humantask.HumanTaskTransition; -import org.jbpm.process.instance.impl.workitem.Active; -import org.jbpm.process.instance.impl.workitem.Complete; import org.junit.jupiter.api.Test; import org.kie.kogito.Application; import org.kie.kogito.Model; -import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.codegen.AbstractCodegenIT; import org.kie.kogito.codegen.data.Address; import org.kie.kogito.codegen.data.Person; import org.kie.kogito.codegen.data.PersonWithAddress; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandler; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.Processes; import org.kie.kogito.process.WorkItem; -import org.kie.kogito.process.workitem.Policy; import static org.assertj.core.api.Assertions.assertThat; public class CallActivityTaskIT extends AbstractCodegenIT { - private Policy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john")); + private Policy securityPolicy = SecurityPolicy.of("john", Collections.emptyList()); @Test public void testBasicCallActivityTask() throws Exception { @@ -151,10 +151,11 @@ public void testCallActivityTaskWithExpressionsForIO() throws Exception { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("MyTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(UserTaskKogitoWorkItemHandler.ACTIVATED.getName()); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.completeTransition(workItems.get(0).getPhaseStatus(), parameters, securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @@ -190,11 +191,10 @@ public void testCallActivityTaskWithExpressionsForIONested() throws Exception { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("MyTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); - - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.completeTransition(workItems.get(0).getPhaseStatus(), parameters, securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @@ -221,4 +221,5 @@ public void testBasicCallActivityTaskWithSingleVarExpression() throws Exception .containsEntry("y", "new value") .containsEntry("x", "a"); } + } diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/PublishEventIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/PublishEventIT.java index d95c2e9e684..39efe723397 100644 --- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/PublishEventIT.java +++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/PublishEventIT.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test; import org.kie.kogito.Application; import org.kie.kogito.Model; -import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.codegen.AbstractCodegenIT; import org.kie.kogito.event.DataEvent; @@ -44,18 +43,26 @@ import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; import org.kie.kogito.event.usertask.UserTaskInstanceStateEventBody; +import org.kie.kogito.internal.process.workitem.Policy; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessError; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.Processes; import org.kie.kogito.process.WorkItem; import org.kie.kogito.uow.UnitOfWork; +import org.kie.kogito.usertask.UserTaskConfig; +import org.kie.kogito.usertask.UserTaskEventListener; +import org.kie.kogito.usertask.events.UserTaskStateEvent; +import org.kie.kogito.usertask.impl.DefaultUserTaskEventListenerConfig; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; public class PublishEventIT extends AbstractCodegenIT { + private Policy securityPolicy = SecurityPolicy.of("john", emptyList()); + @Test public void testProcessWithMilestoneEvents() throws Exception { Application app = generateCodeProcessesOnly("cases/milestones/SimpleMilestone.bpmn"); @@ -160,6 +167,16 @@ public void testBasicUserTaskProcess() throws Exception { Application app = generateCodeProcessesOnly("usertask/UserTasksProcess.bpmn2"); assertThat(app).isNotNull(); + ((DefaultUserTaskEventListenerConfig) app.config().get(UserTaskConfig.class).userTaskEventListeners()).addUserTaskEventListener(new UserTaskEventListener() { + + @Override + public void onUserTaskState(UserTaskStateEvent event) { + System.out.println(event); + + } + + }); + Process p = app.get(Processes.class).processById("UserTasksProcess"); Model m = p.createModel(); @@ -192,13 +209,13 @@ public void testBasicUserTaskProcess() throws Exception { assertThat(userFirstTask).isPresent(); assertUserTaskInstanceEvent(userFirstTask.get(), "FirstTask", null, "1", "Ready", "UserTasksProcess", "First Task"); - List workItems = processInstance.workItems(SecurityPolicy.of(IdentityProviders.of("john"))); + List workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); assertThat(workItems.get(0).getName()).isEqualTo("FirstTask"); uow = app.unitOfWorkManager().newUnitOfWork(); uow.start(); - processInstance.completeWorkItem(workItems.get(0).getId(), null, SecurityPolicy.of(IdentityProviders.of("john"))); + processInstance.completeWorkItem(workItems.get(0).getId(), null, securityPolicy); uow.end(); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); events = publisher.extract(); @@ -215,13 +232,13 @@ public void testBasicUserTaskProcess() throws Exception { assertUserTaskInstanceEvent(firstUserTaskInstance.get(), "SecondTask", null, "1", "Ready", "UserTasksProcess", "Second Task"); assertUserTaskInstanceEvent(secondUserTaskInstance.get(), "FirstTask", null, "1", "Completed", "UserTasksProcess", "First Task"); - workItems = processInstance.workItems(SecurityPolicy.of(IdentityProviders.of("john"))); + workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); assertThat(workItems.get(0).getName()).isEqualTo("SecondTask"); uow = app.unitOfWorkManager().newUnitOfWork(); uow.start(); - processInstance.completeWorkItem(workItems.get(0).getId(), null, SecurityPolicy.of(IdentityProviders.of("john"))); + processInstance.completeWorkItem(workItems.get(0).getId(), null, securityPolicy); uow.end(); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); events = publisher.extract(); @@ -235,7 +252,7 @@ public void testBasicUserTaskProcess() throws Exception { left = findNodeInstanceEvents(events, 2); assertThat(left).hasSize(2).extractingResultOf("getNodeType").containsOnly("HumanTaskNode", "EndNode"); - assertUserTaskInstanceEvent(events.get(1), "SecondTask", null, "1", "Completed", "UserTasksProcess", "Second Task"); + assertUserTaskInstanceEvent(events.get(0), "SecondTask", null, "1", "Completed", "UserTasksProcess", "Second Task"); } @Test @@ -272,7 +289,7 @@ public void testBasicUserTaskProcessAbort() throws Exception { assertThat(event).isPresent(); assertUserTaskInstanceEvent(event.get(), "FirstTask", null, "1", "Ready", "UserTasksProcess", "First Task"); - List workItems = processInstance.workItems(SecurityPolicy.of(IdentityProviders.of("john"))); + List workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); assertThat(workItems.get(0).getName()).isEqualTo("FirstTask"); @@ -282,12 +299,12 @@ public void testBasicUserTaskProcessAbort() throws Exception { uow.end(); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ABORTED); events = publisher.extract(); - assertThat(events).hasSize(4); + assertThat(events).hasSize(3); triggered = findNodeInstanceEvents(events, ProcessInstanceNodeEventBody.EVENT_TYPE_ABORTED); assertThat(triggered).hasSize(1).extractingResultOf("getNodeName").containsOnly("First Task"); - assertProcessInstanceEvent(events.get(3), "UserTasksProcess", "UserTasksProcess", ProcessInstance.STATE_ABORTED); + assertProcessInstanceEvent(events.get(2), "UserTasksProcess", "UserTasksProcess", ProcessInstance.STATE_ABORTED); } diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/SignalEventIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/SignalEventIT.java index af99481a6f4..da2c3bec808 100644 --- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/SignalEventIT.java +++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/SignalEventIT.java @@ -88,6 +88,7 @@ public void testIntermediateEndSignal() throws Exception { public void testIntermediateSignalEventWithData() throws Exception { Map> resourcesTypeMap = new HashMap<>(); resourcesTypeMap.put(TYPE.PROCESS, Collections.singletonList("signalevent/IntermediateCatchEventSignal.bpmn2")); + resourcesTypeMap.put(TYPE.USER_TASK, Collections.singletonList("signalevent/IntermediateCatchEventSignal.bpmn2")); Application app = generateCode(resourcesTypeMap); assertThat(app).isNotNull(); @@ -139,6 +140,7 @@ public void testIntermediateSignalEventWithData() throws Exception { public void testBoundarySignalEventWithData() throws Exception { Map> resourcesTypeMap = new HashMap<>(); resourcesTypeMap.put(TYPE.PROCESS, Collections.singletonList("signalevent/BoundarySignalEventOnTask.bpmn2")); + resourcesTypeMap.put(TYPE.USER_TASK, Collections.singletonList("signalevent/BoundarySignalEventOnTask.bpmn2")); Application app = generateCode(resourcesTypeMap); assertThat(app).isNotNull(); @@ -177,6 +179,7 @@ public void testBoundarySignalEventWithData() throws Exception { public void testBoundaryInterruptingSignalEventWithData() throws Exception { Map> resourcesTypeMap = new HashMap<>(); resourcesTypeMap.put(TYPE.PROCESS, Collections.singletonList("signalevent/BoundaryInterruptingSignalEventOnTask.bpmn2")); + resourcesTypeMap.put(TYPE.USER_TASK, Collections.singletonList("signalevent/BoundaryInterruptingSignalEventOnTask.bpmn2")); Application app = generateCode(resourcesTypeMap); assertThat(app).isNotNull(); @@ -204,6 +207,7 @@ public void testBoundaryInterruptingSignalEventWithData() throws Exception { public void testIntermediateSignalEventWithDataControlledByUnitOfWork() throws Exception { Map> resourcesTypeMap = new HashMap<>(); resourcesTypeMap.put(TYPE.PROCESS, Collections.singletonList("signalevent/IntermediateCatchEventSignal.bpmn2")); + resourcesTypeMap.put(TYPE.USER_TASK, Collections.singletonList("signalevent/IntermediateCatchEventSignal.bpmn2")); Application app = generateCode(resourcesTypeMap); assertThat(app).isNotNull(); // create first unit of work diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java index a5e6cb2abaa..dc15d15ae9f 100644 --- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java +++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/tests/UserTaskIT.java @@ -26,11 +26,7 @@ import java.util.Map; import java.util.Optional; -import org.jbpm.process.instance.impl.humantask.HumanTaskTransition; -import org.jbpm.process.instance.impl.humantask.phases.Claim; -import org.jbpm.process.instance.impl.humantask.phases.Release; -import org.jbpm.process.instance.impl.workitem.Active; -import org.jbpm.process.instance.impl.workitem.Complete; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.kie.kogito.Application; import org.kie.kogito.Model; @@ -42,23 +38,34 @@ import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.ProcessWorkItemTransitionEvent; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; +import org.kie.kogito.internal.process.workitem.Policy; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.Processes; import org.kie.kogito.process.VariableViolationException; import org.kie.kogito.process.WorkItem; -import org.kie.kogito.process.workitem.InvalidTransitionException; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.Policy; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; +import static org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandler.ACTIVATED; +import static org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandler.RESERVED; +import static org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandler.TRANSITION_ACTIVATED_CLAIM; +import static org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandler.TRANSITION_RESERVED_COMPLETE; +import static org.kie.kogito.jbpm.usertask.handler.UserTaskKogitoWorkItemHandler.TRANSITION_RESERVED_RELEASE; +@Disabled public class UserTaskIT extends AbstractCodegenIT { - private Policy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john")); + private Policy securityPolicy = SecurityPolicy.of("john", emptyList()); @Test public void testBasicUserTaskProcess() throws Exception { @@ -93,8 +100,18 @@ public void afterWorkItemTransition(ProcessWorkItemTransitionEvent event) { List workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); assertThat(workItems.get(0).getName()).isEqualTo("FirstTask"); + WorkItem wi = workItems.get(0); - processInstance.completeWorkItem(workItems.get(0).getId(), null, securityPolicy); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); @@ -104,7 +121,7 @@ public void afterWorkItemTransition(ProcessWorkItemTransitionEvent event) { processInstance.completeWorkItem(workItems.get(0).getId(), null, securityPolicy); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); - assertThat(workItemTransitionEvents).hasSize(8); + assertThat(workItemTransitionEvents).hasSize(12); } @Test @@ -128,21 +145,28 @@ public void testBasicUserTaskProcessPhases() throws Exception { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); - String workItemId = workItems.get(0).getId(); - processInstance.transitionWorkItem(workItemId, new HumanTaskTransition(Complete.ID, null, securityPolicy)); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + handler = getWorkItemHandler(p, wi); + transition = handler.completeTransition(workItems.get(0).getPhaseStatus(), parameters, securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @@ -167,32 +191,33 @@ public void testBasicUserTaskProcessClaimAndCompletePhases() throws Exception { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); assertThat(wi.getResults()).isEmpty(); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Claim.ID, Collections.singletonMap("test", "value"), securityPolicy)); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), Map.of("ACTUAL_OWNER", "john", "test", "value"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Claim.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Claim.STATUS); - assertThat(wi.getResults()).hasSize(2) - .containsEntry("test", "value") - .containsEntry("ActorId", "john"); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + assertThat(wi.getResults()).hasSize(1) + .containsEntry("test", "value"); + + handler = getWorkItemHandler(p, wi); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), emptyMap(), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); assertThat(wi.getResults()).isEmpty(); processInstance.abort(); @@ -220,33 +245,51 @@ public void testBasicUserTaskProcessReleaseAndCompletePhases() throws Exception assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); assertThat(wi.getResults()).isEmpty(); - final String wiId = wi.getId(); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); - assertThatExceptionOfType(InvalidTransitionException.class).isThrownBy(() -> processInstance.transitionWorkItem(wiId, new HumanTaskTransition(Release.ID, null, securityPolicy))); + WorkItemTransition claim = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(wi.getId(), claim); - assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); + assertThat(wi.getResults()).isEmpty(); + + WorkItemTransition release = handler.newTransition(TRANSITION_RESERVED_RELEASE.id(), wi.getPhaseStatus(), emptyMap(), securityPolicy); + processInstance.transitionWorkItem(wi.getId(), release); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); assertThat(wi.getResults()).isEmpty(); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + claim = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(wi.getId(), claim); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); + assertThat(wi.getResults()).isEmpty(); + WorkItemTransition transition = handler.completeTransition(wi.getPhaseStatus(), emptyMap(), securityPolicy); + processInstance.transitionWorkItem(wi.getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); assertThat(wi.getResults()).isEmpty(); processInstance.abort(); @@ -287,38 +330,37 @@ public void afterWorkItemTransition(ProcessWorkItemTransitionEvent event) { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); assertThat(wi.getResults()).isEmpty(); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Claim.ID, Collections.singletonMap("test", "value"), securityPolicy)); - assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), Map.of("ACTUAL_OWNER", "john", "test", "value"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Claim.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Claim.STATUS); - assertThat(wi.getResults()).hasSize(2) - .containsEntry("test", "value") - .containsEntry("ActorId", "john"); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); + assertThat(wi.getResults()).hasSize(1) + .containsEntry("test", "value"); + + transition = handler.completeTransition(wi.getPhaseStatus(), emptyMap(), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); assertThat(wi.getResults()).isEmpty(); processInstance.abort(); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ABORTED); - assertThat(workItemTransitionEvents).hasSize(10); + assertThat(workItemTransitionEvents).hasSize(12); } @Test @@ -342,8 +384,7 @@ public void testBasicUserTaskProcessClaimAndCompleteWrongUser() throws Exception assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); assertThat(wi.getResults()).isEmpty(); final String wiId = wi.getId(); @@ -352,11 +393,12 @@ public void testBasicUserTaskProcessClaimAndCompleteWrongUser() throws Exception // if user that is not authorized to work on work item both listing and getting by id should apply it List securedWorkItems = processInstance.workItems(SecurityPolicy.of(identity)); assertThat(securedWorkItems).isEmpty(); - assertThatExceptionOfType(WorkItemNotFoundException.class).isThrownBy(() -> processInstance.workItem(wiId, SecurityPolicy.of(identity))); - assertThatExceptionOfType(NotAuthorizedException.class).isThrownBy(() -> processInstance.transitionWorkItem(wiId, new HumanTaskTransition(Claim.ID, null, identity))); + assertThatExceptionOfType(WorkItemNotFoundException.class).isThrownBy(() -> processInstance.workItem(wiId, SecurityPolicy.of(identity))); - assertThatExceptionOfType(NotAuthorizedException.class).isThrownBy(() -> processInstance.completeWorkItem(wiId, null, SecurityPolicy.of(identity))); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition claimKelly = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "kelly"), SecurityPolicy.of(identity)); + assertThatExceptionOfType(NotAuthorizedException.class).isThrownBy(() -> processInstance.transitionWorkItem(wiId, claimKelly)); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); @@ -364,21 +406,28 @@ public void testBasicUserTaskProcessClaimAndCompleteWrongUser() throws Exception assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); assertThat(wi.getResults()).isEmpty(); - IdentityProvider identityCorrect = IdentityProviders.of("john"); - - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, identityCorrect)); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + WorkItemTransition claimJohn = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(wiId, claimJohn); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); + assertThat(wi.getResults()).isEmpty(); + WorkItemTransition completeJohn = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), emptyMap(), securityPolicy); + processInstance.transitionWorkItem(wiId, completeJohn); + workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); assertThat(wi.getResults()).isEmpty(); processInstance.abort(); @@ -401,26 +450,35 @@ public void testApprovalWithExcludedOwnerViaPhases() throws Exception { processInstance.start(); assertThat(processInstance.status()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - IdentityProvider identity = IdentityProviders.of("admin", Collections.singletonList("managers")); + IdentityProvider identity = IdentityProviders.of("manager", emptyList()); SecurityPolicy policy = SecurityPolicy.of(identity); processInstance.workItems(policy); List workItems = processInstance.workItems(policy); assertThat(workItems).hasSize(1); - HumanTaskTransition transition = new HumanTaskTransition(Complete.ID, null, identity); + + WorkItem wi = workItems.get(0); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), singletonMap("ActorId", "manager"), policy); processInstance.transitionWorkItem(workItems.get(0).getId(), transition); // actual owner of the first task is excluded owner on the second task so won't find it workItems = processInstance.workItems(policy); assertThat(workItems).isEmpty(); - identity = IdentityProviders.of("john", Collections.singletonList("managers")); + identity = IdentityProviders.of("john", singletonList("managers")); policy = SecurityPolicy.of(identity); workItems = processInstance.workItems(policy); assertThat(workItems).hasSize(1); + wi = workItems.get(0); + transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), policy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); - transition = new HumanTaskTransition(Complete.ID, null, identity); + workItems = processInstance.workItems(policy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), emptyMap(), policy); processInstance.transitionWorkItem(workItems.get(0).getId(), transition); assertThat(processInstance.status()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); @@ -436,21 +494,20 @@ public void testApprovalWithExcludedOwner() throws Exception { Model m = p.createModel(); Map parameters = new HashMap<>(); + parameters.put("approver", "manager"); m.fromMap(parameters); ProcessInstance processInstance = p.createInstance(m); processInstance.start(); assertThat(processInstance.status()).isEqualTo(KogitoProcessInstance.STATE_ACTIVE); - IdentityProvider identity = IdentityProviders.of("admin", Collections.singletonList("managers")); + IdentityProvider identity = IdentityProviders.of("manager", emptyList()); SecurityPolicy policy = SecurityPolicy.of(identity); - processInstance.workItems(policy); - List workItems = processInstance.workItems(policy); assertThat(workItems).hasSize(1); - processInstance.completeWorkItem(workItems.get(0).getId(), null, policy); + processInstance.completeWorkItem(workItems.get(0).getId(), singletonMap("ActorId", "manager"), policy); // actual owner of the first task is excluded owner on the second task so won't find it workItems = processInstance.workItems(policy); assertThat(workItems).isEmpty(); @@ -461,6 +518,13 @@ public void testApprovalWithExcludedOwner() throws Exception { workItems = processInstance.workItems(policy); assertThat(workItems).hasSize(1); + assertThat(workItems).hasSize(1); + WorkItem wi = workItems.get(0); + + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), policy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + processInstance.completeWorkItem(workItems.get(0).getId(), null, policy); assertThat(processInstance.status()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED); @@ -487,18 +551,26 @@ public void testBasicUserTaskProcessCancelAndTriggerNode() throws Exception { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); + + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); String firstSecondTaskNodeInstanceId = wi.getNodeInstanceId(); @@ -510,11 +582,11 @@ public void testBasicUserTaskProcessCancelAndTriggerNode() throws Exception { assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); // since it was triggered again it must have different node instance id assertThat(wi.getNodeInstanceId()).isNotEqualTo(firstSecondTaskNodeInstanceId); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + transition = handler.completeTransition(workItems.get(0).getPhaseStatus(), parameters, securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @@ -540,18 +612,28 @@ public void testBasicUserTaskProcessCancelAndRetriggerNode() throws Exception { assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); + + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); String firstSecondTaskNodeInstanceId = wi.getNodeInstanceId(); @@ -562,11 +644,13 @@ public void testBasicUserTaskProcessCancelAndRetriggerNode() throws Exception { assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); // since it was retriggered it must have different node instance id assertThat(wi.getNodeInstanceId()).isNotEqualTo(firstSecondTaskNodeInstanceId); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + + transition = handler.completeTransition(workItems.get(0).getPhaseStatus(), parameters, securityPolicy); + processInstance.transitionWorkItem(wi.getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); } @@ -592,57 +676,56 @@ public void testBasicUserTaskProcessClaimReleaseClaimAndCompletePhases() throws assertThat(workItems).hasSize(1); WorkItem wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); assertThat(wi.getResults()).isEmpty(); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Claim.ID, Collections.singletonMap("test", "value"), securityPolicy)); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), Map.of("ACTUAL_OWNER", "john", "test", "value"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Claim.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Claim.STATUS); - assertThat(wi.getResults()).hasSize(2) - .containsEntry("test", "value") - .containsEntry("ActorId", "john"); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Release.ID, null, securityPolicy)); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); + assertThat(wi.getResults()).hasSize(1) + .containsEntry("test", "value"); + + transition = handler.newTransition(TRANSITION_RESERVED_RELEASE.id(), wi.getPhaseStatus(), emptyMap(), securityPolicy); + + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Release.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Release.STATUS); - assertThat(wi.getResults()).hasSize(2) - .containsEntry("test", "value") - .containsEntry("ActorId", "john"); + assertThat(wi.getPhaseStatus()).isEqualTo(ACTIVATED.getName()); + assertThat(wi.getResults()).hasSize(0); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Claim.ID, Collections.singletonMap("test", "value"), securityPolicy)); + transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), Map.of("ACTUAL_OWNER", "john", "test", "value"), securityPolicy); + processInstance.transitionWorkItem(wi.getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("FirstTask"); - assertThat(wi.getPhase()).isEqualTo(Claim.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Claim.STATUS); - assertThat(wi.getResults()).hasSize(2) - .containsEntry("test", "value") - .containsEntry("ActorId", "john"); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); + assertThat(wi.getResults()).hasSize(1) + .containsEntry("test", "value"); - processInstance.transitionWorkItem(workItems.get(0).getId(), new HumanTaskTransition(Complete.ID, null, securityPolicy)); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), emptyMap(), securityPolicy); + processInstance.transitionWorkItem(wi.getId(), transition); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); wi = workItems.get(0); assertThat(wi.getName()).isEqualTo("SecondTask"); - assertThat(wi.getPhase()).isEqualTo(Active.ID); - assertThat(wi.getPhaseStatus()).isEqualTo(Active.STATUS); + assertThat(wi.getPhaseStatus()).isEqualTo(RESERVED.getName()); assertThat(wi.getResults()).isEmpty(); processInstance.abort(); @@ -792,7 +875,7 @@ public void testUserTaskWithIOexpressionProcess() throws Exception { assertThat(workItems.get(0).getName()).isEqualTo("Hello"); assertThat(workItems.get(0).getParameters()).containsEntry("personName", "john"); - processInstance.completeWorkItem(workItems.get(0).getId(), Collections.singletonMap("personAge", 50), securityPolicy); + processInstance.completeWorkItem(workItems.get(0).getId(), singletonMap("personAge", 50), securityPolicy); assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED); Model output = (Model) processInstance.variables(); @@ -829,9 +912,18 @@ public void testBasicUserTaskProcessWithBusinessKey() throws Exception { List workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); assertThat(workItems.get(0).getName()).isEqualTo("FirstTask"); + WorkItem wi = workItems.get(0); - processInstance.completeWorkItem(workItems.get(0).getId(), null, securityPolicy); - assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_ACTIVE); + KogitoWorkItemHandler handler = getWorkItemHandler(p, wi); + WorkItemTransition transition = handler.newTransition(TRANSITION_ACTIVATED_CLAIM.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); + + workItems = processInstance.workItems(securityPolicy); + assertThat(workItems).hasSize(1); + wi = workItems.get(0); + assertThat(wi.getName()).isEqualTo("FirstTask"); + transition = handler.newTransition(TRANSITION_RESERVED_COMPLETE.id(), wi.getPhaseStatus(), singletonMap("ACTUAL_OWNER", "john"), securityPolicy); + processInstance.transitionWorkItem(workItems.get(0).getId(), transition); workItems = processInstance.workItems(securityPolicy); assertThat(workItems).hasSize(1); diff --git a/kogito-codegen-modules/kogito-codegen-processes/pom.xml b/kogito-codegen-modules/kogito-codegen-processes/pom.xml index f020e88a914..f3f05a38a1a 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/pom.xml +++ b/kogito-codegen-modules/kogito-codegen-processes/pom.xml @@ -83,11 +83,6 @@ test-jar test - - org.kie.kogito - process-serialization-protobuf - test - org.junit.jupiter junit-jupiter-engine diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java new file mode 100644 index 00000000000..58bd4a54b61 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java @@ -0,0 +1,263 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.codegen.usertask; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; + +import org.drools.codegen.common.GeneratedFile; +import org.drools.codegen.common.GeneratedFileType; +import org.jbpm.bpmn2.xml.BPMNDISemanticModule; +import org.jbpm.bpmn2.xml.BPMNExtensionsSemanticModule; +import org.jbpm.bpmn2.xml.BPMNSemanticModule; +import org.jbpm.compiler.xml.XmlProcessReader; +import org.jbpm.compiler.xml.core.SemanticModules; +import org.jbpm.process.core.Work; +import org.jbpm.workflow.core.node.HumanTaskNode; +import org.kie.api.definition.process.Process; +import org.kie.api.io.Resource; +import org.kie.kogito.codegen.api.ApplicationSection; +import org.kie.kogito.codegen.api.ConfigGenerator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.api.template.TemplatedGenerator; +import org.kie.kogito.codegen.core.AbstractGenerator; +import org.kie.kogito.codegen.process.ProcessCodegenException; +import org.kie.kogito.codegen.process.ProcessParsingException; +import org.kie.kogito.internal.SupportedExtensions; +import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess; +import org.kie.kogito.process.validation.ValidationException; +import org.kie.kogito.process.validation.ValidationLogDecorator; +import org.xml.sax.SAXException; + +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.expr.CastExpr; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.IntegerLiteralExpr; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.expr.NullLiteralExpr; +import com.github.javaparser.ast.expr.StringLiteralExpr; +import com.github.javaparser.ast.expr.ThisExpr; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt; + +import static java.util.stream.Collectors.toList; +import static org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils.FAIL_ON_ERROR_PROPERTY; + +public class UserTaskCodegen extends AbstractGenerator { + private static final String NODE_NAME = "NodeName"; + private static final String DESCRIPTION = "Description"; + private static final String PRIORITY = "Priority"; + + private static final String ACTOR_ID = "ActorId"; + private static final String GROUP_ID = "GroupId"; + private static final String BUSINESSADMINISTRATOR_ID = "BusinessAdministratorId"; + private static final String BUSINESSADMINISTRATOR_GROUP_ID = "BusinessAdministratorGroupId"; + private static final String EXCLUDED_OWNER_ID = "ExcludedOwnerId"; + + private static final SemanticModules BPMN_SEMANTIC_MODULES; + + static { + BPMN_SEMANTIC_MODULES = new SemanticModules(); + BPMN_SEMANTIC_MODULES.addSemanticModule(new BPMNSemanticModule()); + BPMN_SEMANTIC_MODULES.addSemanticModule(new BPMNExtensionsSemanticModule()); + BPMN_SEMANTIC_MODULES.addSemanticModule(new BPMNDISemanticModule()); + } + + public static final String SECTION_CLASS_NAME = "usertask"; + + TemplatedGenerator templateGenerator; + private List descriptors; + + public UserTaskCodegen(KogitoBuildContext context, List collectedResources) { + super(context, "usertasks"); + this.descriptors = collectedResources; + + templateGenerator = TemplatedGenerator.builder() + .withTemplateBasePath("/class-templates/usertask") + .withTargetTypeName(SECTION_CLASS_NAME) + .build(context, "UserTask"); + } + + @Override + public Optional section() { + return Optional.of(new UserTaskContainerGenerator(this.context(), descriptors)); + } + + @Override + public Optional configGenerator() { + return Optional.of(new UserTaskConfigGenerator(context(), descriptors)); + } + + @Override + public boolean isEmpty() { + return descriptors.isEmpty(); + } + + @Override + protected Collection internalGenerate() { + List generatedFiles = new ArrayList<>(); + for (Work info : descriptors) { + CompilationUnit unit = templateGenerator.compilationUnit().get(); + + String className = UserTaskCodegenHelper.className(info); + String packageName = UserTaskCodegenHelper.packageName(info); + unit.getPackageDeclaration().get().setName(packageName); + + ClassOrInterfaceDeclaration clazzDeclaration = unit.findFirst(ClassOrInterfaceDeclaration.class).get(); + if (context().hasDI()) { + context().getDependencyInjectionAnnotator().withNamedApplicationComponent(clazzDeclaration, UserTaskCodegenHelper.className(info)); + } + clazzDeclaration.setName(className); + + ConstructorDeclaration declaration = clazzDeclaration.findFirst(ConstructorDeclaration.class).get(); + declaration.setName(className); + + String taskNodeName = (String) info.getParameter(NODE_NAME); + Expression taskNameExpression = taskNodeName != null ? new StringLiteralExpr(taskNodeName) : new NullLiteralExpr(); + + BlockStmt block = declaration.getBody(); + NodeList arguments = new NodeList<>(); + if (!context().hasDI()) { + arguments.add(new NameExpr("application")); + } + arguments.add(new StringLiteralExpr((String) info.getParameter(Work.PARAMETER_UNIQUE_TASK_ID))); + arguments.add(taskNameExpression); + block.addStatement(new ExplicitConstructorInvocationStmt().setThis(false).setArguments(arguments)); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setPotentialUsers", NodeList.nodeList(toStringExpression(info.getParameter(ACTOR_ID))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setPotentialGroups", NodeList.nodeList(toStringExpression(info.getParameter(GROUP_ID))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setAdminUsers", NodeList.nodeList(toStringExpression(info.getParameter(BUSINESSADMINISTRATOR_ID))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setAdminGroups", NodeList.nodeList(toStringExpression(info.getParameter(BUSINESSADMINISTRATOR_GROUP_ID))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setExcludedUsers", NodeList.nodeList(toStringExpression(info.getParameter(EXCLUDED_OWNER_ID))))); + + block.addStatement(new MethodCallExpr(new ThisExpr(), "setTaskDescription", NodeList.nodeList(toStringExpression(info.getParameter(DESCRIPTION))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setTaskPriority", NodeList.nodeList(toIntegerExpression(info.getParameter(PRIORITY))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setReferenceName", NodeList.nodeList(toStringExpression(info.getParameter(NODE_NAME))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setSkippable", NodeList.nodeList(toStringExpression(info.getParameter("Skippable"))))); + + block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotStartedDeadLines", NodeList.nodeList(toStringExpression(info.getParameter("NotStartedNotify"))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotCompletedDeadlines", NodeList.nodeList(toStringExpression(info.getParameter("NotCompletedNotify"))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotStartedReassignments", NodeList.nodeList(toStringExpression(info.getParameter("NotCompletedReassign"))))); + block.addStatement(new MethodCallExpr(new ThisExpr(), "setNotCompletedReassigments", NodeList.nodeList(toStringExpression(info.getParameter("NotStartedReassign"))))); + + generatedFiles.add(new GeneratedFile(GeneratedFileType.SOURCE, UserTaskCodegenHelper.path(info).resolve(className + ".java"), unit.toString())); + } + + return generatedFiles; + } + + private Expression toIntegerExpression(Object value) { + if (value == null) { + return new CastExpr(StaticJavaParser.parseType(Integer.class.getName()), new NullLiteralExpr()); + } + + return new IntegerLiteralExpr(value.toString()); + } + + private Expression toStringExpression(Object value) { + if (value == null) { + return new CastExpr(StaticJavaParser.parseType(String.class.getName()), new NullLiteralExpr()); + } + + return new StringLiteralExpr(value.toString()); + } + + public static UserTaskCodegen ofCollectedResources(KogitoBuildContext context, Collection resources) { + Map processesErrors = new HashMap<>(); + Set extensions = SupportedExtensions.getBPMNExtensions(); + Predicate supportExtensions = resource -> extensions.stream().anyMatch(resource.getSourcePath()::endsWith); + + List userTasks = resources.stream() + .map(CollectedResource::resource) + .filter(supportExtensions) + .flatMap(resource -> { + List data = new ArrayList<>(); + try { + for (KogitoWorkflowProcess process : parseProcessFile(resource).stream().map(KogitoWorkflowProcess.class::cast).toList()) { + List descriptors = process.getNodesRecursively() + .stream() + .filter(HumanTaskNode.class::isInstance) + .map(HumanTaskNode.class::cast) + .map(e -> { + Work w = e.getWork(); + w.setParameter("PackageName", process.getPackageName()); + w.setParameter("ProcessId", process.getId()); + if (w.getParameter(Work.PARAMETER_UNIQUE_TASK_ID) == null) { + w.setParameter(Work.PARAMETER_UNIQUE_TASK_ID, e.getUniqueId()); + } + return w; + }) + .toList(); + + data.addAll(descriptors); + } + } catch (ValidationException e) { + processesErrors.put(resource.getSourcePath(), e); + } catch (ProcessParsingException e) { + processesErrors.put(resource.getSourcePath(), e.getCause()); + } + return data.stream(); + + }) + .collect(toList()); + + handleValidation(context, processesErrors); + + return ofUserTasks(context, userTasks); + } + + private static void handleValidation(KogitoBuildContext context, Map processesErrors) { + if (!processesErrors.isEmpty()) { + ValidationLogDecorator decorator = new ValidationLogDecorator(processesErrors); + decorator.decorate(); + //rethrow exception to break the flow after decoration unless property is set to false + if (context.getApplicationProperty(FAIL_ON_ERROR_PROPERTY, Boolean.class).orElse(true)) { + throw new ProcessCodegenException("Processes with errors are " + decorator.toString()); + } + } + } + + private static UserTaskCodegen ofUserTasks(KogitoBuildContext context, List userTasks) { + return new UserTaskCodegen(context, userTasks); + } + + protected static Collection parseProcessFile(Resource r) { + try (Reader reader = r.getReader()) { + XmlProcessReader xmlReader = new XmlProcessReader( + BPMN_SEMANTIC_MODULES, + Thread.currentThread().getContextClassLoader()); + return xmlReader.read(reader); + } catch (SAXException | IOException e) { + throw new ProcessParsingException(e); + } + } +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenFactory.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenFactory.java new file mode 100644 index 00000000000..e8a7c52546c --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenFactory.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.codegen.usertask; + +import java.util.Collection; + +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.GeneratorFactory; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; + +public class UserTaskCodegenFactory implements GeneratorFactory { + + @Override + public Generator create(KogitoBuildContext context, Collection collectedResources) { + return UserTaskCodegen.ofCollectedResources(context, collectedResources); + } + +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenHelper.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenHelper.java new file mode 100644 index 00000000000..d61e4b9ab8b --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegenHelper.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.codegen.usertask; + +import java.io.File; +import java.nio.file.Path; + +import org.jbpm.process.core.Work; +import org.kie.kogito.internal.utils.ConversionUtils; + +public final class UserTaskCodegenHelper { + + private UserTaskCodegenHelper() { + // do nothing; + } + + public static String processId(Work descriptor) { + return ConversionUtils.sanitizeClassName((String) descriptor.getParameter("ProcessId")); + } + + public static String className(Work descriptor) { + return processId(descriptor) + "_" + ConversionUtils.sanitizeClassName((String) descriptor.getParameter(Work.PARAMETER_UNIQUE_TASK_ID)); + } + + public static String packageName(Work descriptor) { + return (String) descriptor.getParameter("PackageName"); + } + + public static Path path(Work descriptor) { + return Path.of(((String) descriptor.getParameter("PackageName")).replaceAll("\\.", File.separator)); + } + + public static String fqnClassName(Work descriptor) { + return packageName(descriptor) + "." + className(descriptor); + } +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskConfigGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskConfigGenerator.java new file mode 100644 index 00000000000..641f3b2d1a5 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskConfigGenerator.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.codegen.usertask; + +import java.io.File; +import java.nio.file.Path; +import java.util.List; + +import org.drools.codegen.common.GeneratedFile; +import org.drools.codegen.common.GeneratedFileType; +import org.jbpm.process.core.Work; +import org.kie.kogito.codegen.api.ConfigGenerator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.template.TemplatedGenerator; + +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.ConstructorDeclaration; + +public class UserTaskConfigGenerator implements ConfigGenerator { + + private List collectedResources; + private TemplatedGenerator templateGenerator; + + public UserTaskConfigGenerator(KogitoBuildContext context, List collectedResources) { + this.collectedResources = collectedResources; + templateGenerator = TemplatedGenerator.builder() + .withTemplateBasePath("/class-templates/usertask") + .build(context, "UserTaskConfig"); + } + + @Override + public String configClassName() { + return "UserTaskConfig"; + } + + @Override + public GeneratedFile generate() { + CompilationUnit unit = templateGenerator.compilationUnit().get(); + String packageName = unit.getPackageDeclaration().get().getNameAsString(); + unit.getPackageDeclaration().get().setName(packageName); + + ClassOrInterfaceDeclaration clazzDeclaration = unit.findFirst(ClassOrInterfaceDeclaration.class).get(); + clazzDeclaration.setName(configClassName()); + + ConstructorDeclaration declaration = clazzDeclaration.findFirst(ConstructorDeclaration.class).get(); + declaration.setName(configClassName()); + + return new GeneratedFile(GeneratedFileType.SOURCE, Path.of(packageName.replaceAll("\\.", File.separator), configClassName() + ".java"), unit.toString()); + } + +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java new file mode 100644 index 00000000000..364ecf03831 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskContainerGenerator.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.codegen.usertask; + +import java.util.List; + +import org.jbpm.process.core.Work; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.template.TemplatedGenerator; +import org.kie.kogito.codegen.core.AbstractApplicationSection; + +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.expr.ObjectCreationExpr; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt; + +import static com.github.javaparser.ast.NodeList.nodeList; + +public class UserTaskContainerGenerator extends AbstractApplicationSection { + + private TemplatedGenerator templateGenerator; + private List descriptors; + + public UserTaskContainerGenerator(KogitoBuildContext context, List descriptors) { + super(context, "UserTasks"); + templateGenerator = TemplatedGenerator.builder() + .withTemplateBasePath("/class-templates/usertask") + .build(context, "UserTasksContainer"); + this.descriptors = descriptors; + } + + @Override + public CompilationUnit compilationUnit() { + CompilationUnit unit = templateGenerator.compilationUnitOrThrow("Not found"); + + if (context.hasDI()) { + return unit; + } + + ClassOrInterfaceDeclaration clazzUnit = unit.findFirst(ClassOrInterfaceDeclaration.class).get(); + + ConstructorDeclaration constructor = clazzUnit.findFirst(ConstructorDeclaration.class).get(); + + BlockStmt block = new BlockStmt(); + NodeList arguments = new NodeList<>(); + arguments.add(new NameExpr("application")); + for (Work descriptor : descriptors) { + String fqn = UserTaskCodegenHelper.fqnClassName(descriptor); + arguments.add(new ObjectCreationExpr().setType(StaticJavaParser.parseClassOrInterfaceType(fqn)).setArguments(nodeList(new NameExpr("application")))); + } + block.addStatement(new ExplicitConstructorInvocationStmt().setThis(false).setArguments(arguments)); + constructor.setBody(block); + + return unit; + } + +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/META-INF/services/org.kie.kogito.codegen.api.GeneratorFactory b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/META-INF/services/org.kie.kogito.codegen.api.GeneratorFactory index c41776afc44..3c64887b163 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/META-INF/services/org.kie.kogito.codegen.api.GeneratorFactory +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/META-INF/services/org.kie.kogito.codegen.api.GeneratorFactory @@ -17,4 +17,5 @@ # under the License. # -org.kie.kogito.codegen.process.ProcessCodegenFactory \ No newline at end of file +org.kie.kogito.codegen.process.ProcessCodegenFactory +org.kie.kogito.codegen.usertask.UserTaskCodegenFactory \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java index bd40424d924..0bbf0b10a6c 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java @@ -52,15 +52,15 @@ import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.ProcessService; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.AttachmentInfo; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.Policies; import org.kie.kogito.process.workitem.TaskModel; import org.kie.kogito.auth.IdentityProvider; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.AttachmentInfo; +import org.kie.kogito.usertask.model.Comment; + @Path("/$name$") public class $Type$Resource { @@ -144,7 +144,7 @@ public class $Type$Resource { public List getTasks_$name$(@PathParam("id") String id, @QueryParam("user") final String user, @QueryParam("group") final List groups) { - return processService.getTasks(process, id, SecurityPolicy.of(IdentityProviders.of(user, groups))) + return processService.getWorkItems(process, id, SecurityPolicy.of(IdentityProviders.of(user, groups))) .orElseThrow(NotFoundException::new) .stream() .map($TaskModelFactory$::from) diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java index 9fd4d254aa9..9c15e01b473 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java @@ -30,15 +30,15 @@ import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.ProcessService; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.AttachmentInfo; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.Policies; import org.kie.kogito.process.workitem.TaskModel; import org.kie.kogito.auth.IdentityProvider; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.AttachmentInfo; +import org.kie.kogito.usertask.model.Comment; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -129,7 +129,7 @@ public class $Type$Resource { public List getTasks_$name$(@PathVariable("id") String id, @RequestParam(value = "user", required = false) final String user, @RequestParam(value = "group", required = false) final List groups) { - return processService.getTasks(process, id, SecurityPolicy.of(IdentityProviders.of(user, groups))) + return processService.getWorkItems(process, id, SecurityPolicy.of(IdentityProviders.of(user, groups))) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)) .stream() .map($TaskModelFactory$::from) diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java index fa858163fe7..36f93ac4624 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java @@ -41,10 +41,10 @@ public class $Type$Resource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response signal(@PathParam("id") final String id, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - @Context UriInfo uriInfo) { - return processService.signalTask(process, id, "$taskName$", SecurityPolicy.of(user, groups)) + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + @Context UriInfo uriInfo) { + return processService.signalWorkItem(process, id, "$taskName$", SecurityPolicy.of(user, groups)) .map(task -> Response .created(uriInfo.getAbsolutePathBuilder().path(task.getId()).build()) .entity(task.getResults()) @@ -57,12 +57,12 @@ public Response signal(@PathParam("id") final String id, @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public $Type$Output completeTask(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("phase") @DefaultValue("complete") final String phase, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - final $TaskOutput$ model) { - return processService.taskTransition(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) + @PathParam("taskId") final String taskId, + @QueryParam("phase") @DefaultValue("complete") final String phase, + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + final $TaskOutput$ model) { + return processService.transitionWorkItem(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) .orElseThrow(NotFoundException::new); } @@ -70,11 +70,11 @@ public Response signal(@PathParam("id") final String id, @Path("/{id}/$taskName$/{taskId}") @Consumes(MediaType.APPLICATION_JSON) public $TaskOutput$ saveTask(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - final $TaskOutput$ model) { - return processService.saveTask(process, id, taskId, SecurityPolicy.of(user, groups), model, $TaskOutput$::fromMap) + @PathParam("taskId") final String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + final $TaskOutput$ model) { + return processService.setWorkItemOutput(process, id, taskId, SecurityPolicy.of(user, groups), model, $TaskOutput$::fromMap) .orElseThrow(NotFoundException::new); } @@ -89,18 +89,18 @@ public Response signal(@PathParam("id") final String id, @QueryParam("user") final String user, @QueryParam("group") final List groups, final $TaskOutput$ model) { - return processService.taskTransition(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) + return processService.transitionWorkItem(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) .orElseThrow(NotFoundException::new); } @GET @Path("/{id}/$taskName$/{taskId}") @Produces(MediaType.APPLICATION_JSON) - public $TaskModel$ getTask(@PathParam("id") String id, - @PathParam("taskId") String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { - return processService.getTask(process, id, taskId, SecurityPolicy.of(user, groups), $TaskModel$::from) + public $TaskModel$ getWorkItem(@PathParam("id") String id, + @PathParam("taskId") String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { + return processService.getWorkItem(process, id, taskId, SecurityPolicy.of(user, groups), $TaskModel$::from) .orElseThrow(NotFoundException::new); } @@ -108,11 +108,11 @@ public Response signal(@PathParam("id") final String id, @Path("/{id}/$taskName$/{taskId}") @Produces(MediaType.APPLICATION_JSON) public $Type$Output abortTask(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("phase") @DefaultValue("abort") final String phase, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { - return processService.taskTransition(process, id, taskId, phase, SecurityPolicy.of(user, groups), null) + @PathParam("taskId") final String taskId, + @QueryParam("phase") @DefaultValue("abort") final String phase, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { + return processService.transitionWorkItem(process, id, taskId, phase, SecurityPolicy.of(user, groups), null) .orElseThrow(NotFoundException::new); } @@ -127,10 +127,10 @@ public Map getSchema() { @Path("/{id}/$taskName$/{taskId}/schema") @Produces(MediaType.APPLICATION_JSON) public Map getSchemaAndPhases(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { - return processService.getSchemaAndPhases(process, id, taskId, "$taskName$", SecurityPolicy.of(user, groups)); + @PathParam("taskId") final String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { + return processService.getWorkItemSchemaAndPhases(process, id, taskId, "$taskName$", SecurityPolicy.of(user, groups)); } @POST @@ -138,11 +138,11 @@ public Map getSchemaAndPhases(@PathParam("id") final String id, @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.APPLICATION_JSON) public Response addComment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - String commentInfo, - @Context UriInfo uriInfo) { + @PathParam("taskId") final String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + String commentInfo, + @Context UriInfo uriInfo) { return processService.addComment(process, id, taskId, SecurityPolicy.of(user, groups), commentInfo) .map(comment -> Response.created(uriInfo.getAbsolutePathBuilder().path(comment.getId().toString()).build()) .entity(comment).build()) @@ -154,11 +154,11 @@ public Response addComment(@PathParam("id") final String id, @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.APPLICATION_JSON) public Comment updateComment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @PathParam("commentId") final String commentId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - String comment) { + @PathParam("taskId") final String taskId, + @PathParam("commentId") final String commentId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + String comment) { return processService.updateComment(process, id, taskId, commentId, SecurityPolicy.of(user, groups), comment) .orElseThrow(NotFoundException::new); } @@ -166,10 +166,10 @@ public Comment updateComment(@PathParam("id") final String id, @DELETE @Path("/{id}/$taskName$/{taskId}/comments/{commentId}") public Response deleteComment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @PathParam("commentId") final String commentId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { + @PathParam("taskId") final String taskId, + @PathParam("commentId") final String commentId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { return processService.deleteComment(process, id, taskId, commentId, SecurityPolicy.of(user, groups)) .map(removed -> (removed ? Response.ok() : Response.status(Status.NOT_FOUND)).build()) .orElseThrow(NotFoundException::new); @@ -180,11 +180,11 @@ public Response deleteComment(@PathParam("id") final String id, @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response addAttachment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - AttachmentInfo attachmentInfo, - @Context UriInfo uriInfo) { + @PathParam("taskId") final String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + AttachmentInfo attachmentInfo, + @Context UriInfo uriInfo) { return processService.addAttachment(process, id, taskId, SecurityPolicy.of(user, groups), attachmentInfo) .map(attachment -> Response .created(uriInfo.getAbsolutePathBuilder().path(attachment.getId().toString()).build()) @@ -197,11 +197,11 @@ public Response addAttachment(@PathParam("id") final String id, @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Attachment updateAttachment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @PathParam("attachmentId") final String attachmentId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups, - AttachmentInfo attachment) { + @PathParam("taskId") final String taskId, + @PathParam("attachmentId") final String attachmentId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups, + AttachmentInfo attachment) { return processService.updateAttachment(process, id, taskId, attachmentId, SecurityPolicy.of(user, groups), attachment) .orElseThrow(NotFoundException::new); } @@ -209,10 +209,10 @@ public Attachment updateAttachment(@PathParam("id") final String id, @DELETE @Path("/{id}/$taskName$/{taskId}/attachments/{attachmentId}") public Response deleteAttachment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @PathParam("attachmentId") final String attachmentId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { + @PathParam("taskId") final String taskId, + @PathParam("attachmentId") final String attachmentId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { return processService.deleteAttachment(process, id, taskId, attachmentId, SecurityPolicy.of(user, groups)) .map(removed -> (removed ? Response.ok() : Response.status(Status.NOT_FOUND)).build()) .orElseThrow(NotFoundException::new); @@ -222,10 +222,10 @@ public Response deleteAttachment(@PathParam("id") final String id, @Path("/{id}/$taskName$/{taskId}/attachments/{attachmentId}") @Produces(MediaType.APPLICATION_JSON) public Attachment getAttachment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @PathParam("attachmentId") final String attachmentId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { + @PathParam("taskId") final String taskId, + @PathParam("attachmentId") final String attachmentId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { return processService.getAttachment(process, id, taskId, attachmentId, SecurityPolicy.of(user, groups)) .orElseThrow(() -> new NotFoundException("Attachment " + attachmentId + " not found")); } @@ -234,9 +234,9 @@ public Attachment getAttachment(@PathParam("id") final String id, @Path("/{id}/$taskName$/{taskId}/attachments") @Produces(MediaType.APPLICATION_JSON) public Collection getAttachments(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { + @PathParam("taskId") final String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { return processService.getAttachments(process, id, taskId, SecurityPolicy.of(user, groups)) .orElseThrow(NotFoundException::new); } @@ -245,10 +245,10 @@ public Collection getAttachments(@PathParam("id") final String id, @Path("/{id}/$taskName$/{taskId}/comments/{commentId}") @Produces(MediaType.APPLICATION_JSON) public Comment getComment(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @PathParam("commentId") final String commentId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { + @PathParam("taskId") final String taskId, + @PathParam("commentId") final String commentId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { return processService.getComment(process, id, taskId, commentId, SecurityPolicy.of(user, groups)) .orElseThrow(() -> new NotFoundException("Comment " + commentId + " not found")); } @@ -257,9 +257,9 @@ public Comment getComment(@PathParam("id") final String id, @Path("/{id}/$taskName$/{taskId}/comments") @Produces(MediaType.APPLICATION_JSON) public Collection getComments(@PathParam("id") final String id, - @PathParam("taskId") final String taskId, - @QueryParam("user") final String user, - @QueryParam("group") final List groups) { + @PathParam("taskId") final String taskId, + @QueryParam("user") final String user, + @QueryParam("group") final List groups) { return processService.getComments(process, id, taskId, SecurityPolicy.of(user, groups)) .orElseThrow(NotFoundException::new); } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java index 9779d13e7f6..a18e56c3379 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; -import org.jbpm.process.instance.impl.humantask.HumanTaskHelper; import org.jbpm.util.JsonSchemaUtil; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; @@ -29,7 +28,6 @@ import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.impl.Sig; import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.Policies; import org.kie.kogito.process.workitem.TaskMetaInfo; import org.kie.kogito.services.uow.UnitOfWorkExecutor; import org.springframework.http.MediaType; @@ -48,15 +46,15 @@ public class $Type$Resource { @PostMapping(value = "/{id}/$taskName$", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity signal(@PathVariable("id") final String id, - @RequestParam("user") final String user, - @RequestParam("group") final List groups, - final UriComponentsBuilder uriComponentsBuilder) { + @RequestParam("user") final String user, + @RequestParam("group") final List groups, + final UriComponentsBuilder uriComponentsBuilder) { - return processService.signalTask(process, id, "$taskName$", SecurityPolicy.of(user, groups)) + return processService.signalWorkItem(process, id, "$taskName$", SecurityPolicy.of(user, groups)) .map(task -> ResponseEntity .created(uriComponentsBuilder - .path("/$name$/{id}/$taskName$/{taskId}") - .buildAndExpand(id, task.getId()).toUri()) + .path("/$name$/{id}/$taskName$/{taskId}") + .buildAndExpand(id, task.getId()).toUri()) .body(task.getResults())) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @@ -64,59 +62,59 @@ public ResponseEntity signal(@PathVariable("id") final String id, @PostMapping(value = "/{id}/$taskName$/{taskId}/phases/{phase}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) public $Type$Output completeTask(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("phase") final String phase, - @RequestParam("user") final String user, - @RequestParam("group") final List groups, - @RequestBody(required = false) final $TaskOutput$ model) { - return processService.taskTransition(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) + @PathVariable("taskId") final String taskId, + @PathVariable("phase") final String phase, + @RequestParam("user") final String user, + @RequestParam("group") final List groups, + @RequestBody(required = false) final $TaskOutput$ model) { + return processService.transitionWorkItem(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @PutMapping(value = "/{id}/$taskName$/{taskId}", consumes = MediaType.APPLICATION_JSON_VALUE) public $TaskOutput$ saveTask(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", required = false) final List groups, - @RequestBody(required = false) final $TaskOutput$ model) { - return processService.saveTask(process, id, taskId, SecurityPolicy.of(user, groups), model, $TaskOutput$::fromMap) + @PathVariable("taskId") final String taskId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", required = false) final List groups, + @RequestBody(required = false) final $TaskOutput$ model) { + return processService.setWorkItemOutput(process, id, taskId, SecurityPolicy.of(user, groups), model, $TaskOutput$::fromMap) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @PostMapping(value = "/{id}/$taskName$/{taskId}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) public $Type$Output taskTransition(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "phase", required = false, - defaultValue = "complete") final String phase, - @RequestParam(value = "user", - required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups, - @RequestBody(required = false) final $TaskOutput$ model) { - return processService.taskTransition(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) + @PathVariable("taskId") final String taskId, + @RequestParam(value = "phase", required = false, + defaultValue = "complete") final String phase, + @RequestParam(value = "user", + required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups, + @RequestBody(required = false) final $TaskOutput$ model) { + return processService.transitionWorkItem(process, id, taskId, phase, SecurityPolicy.of(user, groups), model) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @GetMapping(value = "/{id}/$taskName$/{taskId}", produces = MediaType.APPLICATION_JSON_VALUE) public $TaskModel$ getTask(@PathVariable("id") String id, - @PathVariable("taskId") String taskId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups) { - return processService.getTask(process, id, taskId, SecurityPolicy.of(user, groups), $TaskModel$::from) + @PathVariable("taskId") String taskId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups) { + return processService.getWorkItem(process, id, taskId, SecurityPolicy.of(user, groups), $TaskModel$::from) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @DeleteMapping(value = "/{id}/$taskName$/{taskId}", produces = MediaType.APPLICATION_JSON_VALUE) public $Type$Output abortTask(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "phase", required = false, - defaultValue = "abort") final String phase, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups) { - return processService.taskTransition(process, id, taskId, phase, SecurityPolicy.of(user, groups), null) + @PathVariable("taskId") final String taskId, + @RequestParam(value = "phase", required = false, + defaultValue = "abort") final String phase, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups) { + return processService.transitionWorkItem(process, id, taskId, phase, SecurityPolicy.of(user, groups), null) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @@ -127,26 +125,26 @@ public Map getSchema() { @GetMapping(value = "/{id}/$taskName$/{taskId}/schema", produces = MediaType.APPLICATION_JSON_VALUE) public Map getSchemaAndPhases(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups) { - return processService.getSchemaAndPhases(process, id, taskId, "$taskName$", SecurityPolicy.of(user, groups)); + @PathVariable("taskId") final String taskId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups) { + return processService.getWorkItemSchemaAndPhases(process, id, taskId, "$taskName$", SecurityPolicy.of(user, groups)); } @PostMapping(value = "/{id}/$taskName$/{taskId}/comments", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity addComment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups, - @RequestBody String commentInfo, - UriComponentsBuilder uriComponentsBuilder) { + @PathVariable("taskId") final String taskId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups, + @RequestBody String commentInfo, + UriComponentsBuilder uriComponentsBuilder) { return processService.addComment(process, id, taskId, SecurityPolicy.of(user, groups), commentInfo) .map(comment -> ResponseEntity .created(uriComponentsBuilder.path("/$name$/{id}/$taskName$/{taskId}/comments/{commentId}") - .buildAndExpand(id, taskId, comment.getId().toString()).toUri()) + .buildAndExpand(id, taskId, comment.getId().toString()).toUri()) .body(comment)) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @@ -154,22 +152,22 @@ public ResponseEntity addComment(@PathVariable("id") final String id, @PutMapping(value = "/{id}/$taskName$/{taskId}/comments/{commentId}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.TEXT_PLAIN_VALUE) public Comment updateComment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("commentId") final String commentId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups, - @RequestBody String comment) { + @PathVariable("taskId") final String taskId, + @PathVariable("commentId") final String commentId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups, + @RequestBody String comment) { return processService.updateComment(process, id, taskId, commentId, SecurityPolicy.of(user, groups), comment) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @DeleteMapping(value = "/{id}/$taskName$/{taskId}/comments/{commentId}") public ResponseEntity deleteComment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("commentId") final String commentId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", required = false) final List groups) { + @PathVariable("taskId") final String taskId, + @PathVariable("commentId") final String commentId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", required = false) final List groups) { return processService.deleteComment(process, id, taskId, commentId, SecurityPolicy.of(user, groups)) .map(removed -> (removed ? ResponseEntity.ok().build() : ResponseEntity.notFound().build())) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); @@ -178,18 +176,19 @@ public ResponseEntity deleteComment(@PathVariable("id") final String id, @PostMapping(value = "/{id}/$taskName$/{taskId}/attachments", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity addAttachment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups, - @RequestBody AttachmentInfo attachmentInfo, - UriComponentsBuilder uriComponentsBuilder) { + @PathVariable("taskId") final String taskId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups, + @RequestBody AttachmentInfo attachmentInfo, + UriComponentsBuilder uriComponentsBuilder) { return processService.addAttachment(process, id, taskId, SecurityPolicy.of(user, groups), attachmentInfo) .map(attachment -> ResponseEntity .created(uriComponentsBuilder.path( "/$name$/{id}/$taskName$/{taskId}/attachments/{attachmentId}") - .buildAndExpand(id, - taskId, attachment.getId()).toUri()) + .buildAndExpand(id, + taskId, attachment.getId()) + .toUri()) .body(attachment)) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @@ -197,68 +196,63 @@ public ResponseEntity addAttachment(@PathVariable("id") final String @PutMapping(value = "/{id}/$taskName$/{taskId}/attachments/{attachmentId}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) public Attachment updateAttachment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("attachmentId") final String attachmentId, - @RequestParam(value = "user", - required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups, - @RequestBody AttachmentInfo attachment) { + @PathVariable("taskId") final String taskId, + @PathVariable("attachmentId") final String attachmentId, + @RequestParam(value = "user", + required = false) final String user, + @RequestParam(value = "group", + required = false) final List groups, + @RequestBody AttachmentInfo attachment) { return processService.updateAttachment(process, id, taskId, attachmentId, SecurityPolicy.of(user, groups), attachment) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @DeleteMapping(value = "/{id}/$taskName$/{taskId}/attachments/{attachmentId}") public ResponseEntity deleteAttachment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("attachmentId") final String attachmentId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", required = false) final List groups) { + @PathVariable("taskId") final String taskId, + @PathVariable("attachmentId") final String attachmentId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", required = false) final List groups) { return processService.deleteAttachment(process, id, taskId, attachmentId, SecurityPolicy.of(user, groups)) .map(removed -> (removed ? ResponseEntity.ok() : ResponseEntity.notFound()).build()) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } - @GetMapping(value = "/{id}/$taskName$/{taskId}/attachments/{attachmentId}", - produces = MediaType.APPLICATION_JSON_VALUE) + @GetMapping(value = "/{id}/$taskName$/{taskId}/attachments/{attachmentId}", produces = MediaType.APPLICATION_JSON_VALUE) public Attachment getAttachment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("attachmentId") final String attachmentId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups) { + @PathVariable("taskId") final String taskId, + @PathVariable("attachmentId") final String attachmentId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", required = false) final List groups) { return processService.getAttachment(process, id, taskId, attachmentId, SecurityPolicy.of(user, groups)) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Attachment " + attachmentId + " not found")); } @GetMapping(value = "/{id}/$taskName$/{taskId}/attachments", produces = MediaType.APPLICATION_JSON_VALUE) public Collection getAttachments(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "user") final String user, - @RequestParam(value = "group") final List groups) { + @PathVariable("taskId") final String taskId, + @RequestParam(value = "user") final String user, + @RequestParam(value = "group") final List groups) { return processService.getAttachments(process, id, taskId, SecurityPolicy.of(user, groups)) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } @GetMapping(value = "/{id}/$taskName$/{taskId}/comments/{commentId}", produces = MediaType.APPLICATION_JSON_VALUE) public Comment getComment(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @PathVariable("commentId") final String commentId, - @RequestParam(value = "user", required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups) { + @PathVariable("taskId") final String taskId, + @PathVariable("commentId") final String commentId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", required = false) final List groups) { return processService.getComment(process, id, taskId, commentId, SecurityPolicy.of(user, groups)) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Comment " + commentId + " not found")); } @GetMapping(value = "/{id}/$taskName$/{taskId}/comments", produces = MediaType.APPLICATION_JSON_VALUE) public Collection getComments(@PathVariable("id") final String id, - @PathVariable("taskId") final String taskId, - @RequestParam(value = "user", - required = false) final String user, - @RequestParam(value = "group", - required = false) final List groups) { + @PathVariable("taskId") final String taskId, + @RequestParam(value = "user", required = false) final String user, + @RequestParam(value = "group", required = false) final List groups) { return processService.getComments(process, id, taskId, SecurityPolicy.of(user, groups)) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java index c10c9a7bb67..1f8979b8759 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java @@ -18,6 +18,9 @@ */ package org.jbpm.process.codegen; +import org.kie.kogito.usertask.model.Attachment; +import org.kie.kogito.usertask.model.AttachmentInfo; +import org.kie.kogito.usertask.model.Comment; import org.kie.kogito.process.workitem.TaskModel; public class $TaskModelFactory$ { diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigJavaTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigJavaTemplate.java new file mode 100644 index 00000000000..737f3f3af08 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigJavaTemplate.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import org.kie.kogito.usertask.impl.DefaultUserTaskConfig; + + +public class UserTaskConfig extends DefaultUserTaskConfig { + + public UserTaskConfig() { + + } + +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigQuarkusTemplate.java new file mode 100644 index 00000000000..3486fad3843 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigQuarkusTemplate.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import org.kie.api.event.process.ProcessEventListener; +import org.kie.kogito.auth.IdentityProvider; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.jobs.JobsService; +import org.kie.kogito.process.ProcessEventListenerConfig; +import org.kie.kogito.process.ProcessVersionResolver; +import org.kie.kogito.process.WorkItemHandlerConfig; +import org.kie.kogito.uow.UnitOfWorkManager; +import org.kie.kogito.uow.events.UnitOfWorkEventListener; +import org.kie.kogito.usertask.impl.DefaultUserTaskConfig; +import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle; +import org.kie.kogito.usertask.UserTaskEventListenerConfig; + +import jakarta.enterprise.inject.Instance; + +@jakarta.inject.Singleton +public class UserTaskConfig extends DefaultUserTaskConfig { + + + @jakarta.inject.Inject + public UserTaskConfig( + Instance workItemHandlerConfig, + Instance unitOfWorkManager, + Instance jobsService, + Instance identityProvider, + Instance userTaskLifeCycle) { + super(workItemHandlerConfig, + unitOfWorkManager, + jobsService, + identityProvider, + userTaskLifeCycle); + } + +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigSpringTemplate.java new file mode 100644 index 00000000000..d8e00dbc576 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskConfigSpringTemplate.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import java.util.List; + +import org.kie.api.event.process.ProcessEventListener; +import org.kie.kogito.auth.IdentityProvider; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.jobs.JobsService; +import org.kie.kogito.process.ProcessEventListenerConfig; +import org.kie.kogito.process.ProcessVersionResolver; +import org.kie.kogito.process.WorkItemHandlerConfig; +import org.kie.kogito.uow.UnitOfWorkManager; +import org.kie.kogito.uow.events.UnitOfWorkEventListener; +import org.kie.kogito.usertask.impl.DefaultUserTaskConfig; +import org.kie.kogito.usertask.lifecycle.UserTaskLifeCycle; +import org.kie.kogito.usertask.UserTaskEventListenerConfig; + +@org.springframework.stereotype.Component +public class UserTaskConfig extends DefaultUserTaskConfig { + + @org.springframework.beans.factory.annotation.Autowired + public UserTaskConfig( + List workItemHandlerConfig, + List unitOfWorkManager, + List jobsService, + List identityProvider, + List userTaskLifeCycle) { + + super(workItemHandlerConfig, + unitOfWorkManager, + jobsService, + identityProvider, + userTaskLifeCycle); + } + +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskJavaTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskJavaTemplate.java new file mode 100644 index 00000000000..21f674ef018 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskJavaTemplate.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Set; + +import org.kie.kogito.Application; +import org.kie.kogito.usertask.impl.DefaultUserTask; + +public class UserTaskTemplate extends DefaultUserTask { + + public UserTaskTemplate(Application application) { + + } + +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskQuarkusTemplate.java new file mode 100644 index 00000000000..5e915790f91 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskQuarkusTemplate.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Set; + +import org.kie.kogito.Application; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.impl.DefaultUserTask; + +public class UserTaskTemplate extends DefaultUserTask { + + @jakarta.inject.Inject + Application application; + + public UserTaskTemplate() { + + } + + @jakarta.annotation.PostConstruct + public void setup() { + this.setApplication(application); + } +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskSpringTemplate.java new file mode 100644 index 00000000000..64e9aa53542 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTaskSpringTemplate.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Set; + +import org.kie.kogito.Application; +import org.kie.kogito.usertask.UserTask; +import org.kie.kogito.usertask.impl.DefaultUserTask; + +public class UserTaskTemplate extends DefaultUserTask { + + @org.springframework.beans.factory.annotation.Autowired + Application application; + + public UserTaskTemplate() { + + } + + @jakarta.annotation.PostConstruct + public void setup() { + this.setApplication(application); + } +} diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java new file mode 100644 index 00000000000..3b5293ac0e3 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerJavaTemplate.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import org.kie.kogito.usertask.impl.DefaultUserTasks; + +public class UserTasks extends DefaultUserTasks { + + public UserTasks(Application application) { + super(application); + } + +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java new file mode 100644 index 00000000000..9d22ea14eee --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerQuarkusTemplate.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import org.kie.kogito.usertask.UserTask; +import jakarta.enterprise.inject.Instance; + +@jakarta.enterprise.context.ApplicationScoped +public class UserTasks implements org.kie.kogito.usertask.UserTasks { + + @jakarta.inject.Inject + jakarta.enterprise.inject.Instance userTasks; + + private Map mappedUserTask = new HashMap<>(); + + @jakarta.annotation.PostConstruct + public void setup() { + for (UserTask userTask : userTasks) { + mappedUserTask.put(userTask.id(), userTask); + } + } + + public UserTask userTaskById(String userTaskId) { + return mappedUserTask.get(userTaskId); + } + + public Collection userTaskIds() { + return mappedUserTask.keySet(); + } +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java new file mode 100644 index 00000000000..1e65367bfc5 --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/UserTasksContainerSpringTemplate.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.usertask.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import org.kie.kogito.usertask.UserTask; + +@org.springframework.web.context.annotation.ApplicationScope +@org.springframework.stereotype.Component +public class UserTasks implements org.kie.kogito.usertask.UserTasks { + + @org.springframework.beans.factory.annotation.Autowired + Collection userTasks; + + private Map mappedUserTask = new HashMap<>(); + + @jakarta.annotation.PostConstruct + public void setup() { + for (UserTask userTask : userTasks) { + mappedUserTask.put(userTask.id(), userTask); + } + } + + public UserTask userTaskById(String userTaskId) { + return mappedUserTask.get(userTaskId); + } + + public Collection userTaskIds() { + return mappedUserTask.keySet(); + } +} \ No newline at end of file diff --git a/kogito-maven-plugin/pom.xml b/kogito-maven-plugin/pom.xml index cd524a1667a..3079354dc00 100644 --- a/kogito-maven-plugin/pom.xml +++ b/kogito-maven-plugin/pom.xml @@ -74,10 +74,12 @@ org.apache.maven maven-artifact + provided org.apache.maven maven-core + provided org.eclipse.sisu @@ -96,6 +98,7 @@ org.apache.maven maven-plugin-api + provided org.eclipse.sisu diff --git a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java index b279c5eafc1..3f6ef379091 100644 --- a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java +++ b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java @@ -140,7 +140,8 @@ protected Predicate> classSubTypeAvailabilityResolver() { } protected ClassLoader projectClassLoader() throws MojoExecutionException { - return MojoUtil.createProjectClassLoader(this.getClass().getClassLoader(), + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + return MojoUtil.createProjectClassLoader(contextClassLoader, project, outputDirectory, null); diff --git a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java index b1c3c675102..8d4aed73a1a 100644 --- a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java +++ b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java @@ -105,8 +105,8 @@ protected void generateModel() throws MojoExecutionException { setSystemProperties(properties); - ApplicationGenerator appGen = ApplicationGeneratorDiscovery - .discover(discoverKogitoRuntimeContext(projectClassLoader())); + ClassLoader projectClassLoader = projectClassLoader(); + ApplicationGenerator appGen = ApplicationGeneratorDiscovery.discover(discoverKogitoRuntimeContext(projectClassLoader)); Collection generatedFiles; if (generatePartial) { diff --git a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/util/MojoUtil.java b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/util/MojoUtil.java index ae089b4a1a9..57002610145 100644 --- a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/util/MojoUtil.java +++ b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/util/MojoUtil.java @@ -40,11 +40,15 @@ import org.kie.api.builder.ReleaseId; import org.kie.api.builder.model.KieModuleModel; import org.kie.util.maven.support.ReleaseIdImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.setDefaultsforEmptyKieModule; public final class MojoUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(MojoUtil.class); + public static Set getProjectFiles(final MavenProject mavenProject, final List kmoduleDeps) throws DependencyResolutionRequiredException, IOException { @@ -69,8 +73,9 @@ public static ClassLoader createProjectClassLoader(final ClassLoader parentClass try { final Set urls = getProjectFiles(mavenProject, kmoduleDeps); urls.add(outputDirectory.toURI().toURL()); - - return URLClassLoader.newInstance(urls.toArray(new URL[0]), parentClassLoader); + URL[] urlArray = urls.toArray(new URL[urls.size()]); + LOGGER.debug("Creating maven project class loading with: {}", Arrays.asList(urlArray)); + return URLClassLoader.newInstance(urlArray, parentClassLoader); } catch (final DependencyResolutionRequiredException | IOException e) { throw new MojoExecutionException("Error setting up Kie ClassLoader", e); } diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java index 688467deb07..acaa404100c 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.function.Function; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.JsonObjectUtils; import org.kie.kogito.serverless.workflow.SWFConstants; import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplication.java b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplication.java index aaaedd8606d..186d205ee86 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplication.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplication.java @@ -50,7 +50,7 @@ import org.kie.kogito.event.impl.EventFactoryUtils; import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; import org.kie.kogito.internal.process.event.KogitoProcessEventListener; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.ProcessInstancesFactory; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowProcess.java b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowProcess.java index ae47c74bb6b..f676547c4b8 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowProcess.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowProcess.java @@ -25,8 +25,8 @@ import org.kie.kogito.Application; import org.kie.kogito.Model; import org.kie.kogito.correlation.CompositeCorrelation; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.ProcessInstancesFactory; import org.kie.kogito.process.impl.AbstractProcess; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-grpc-runtime/src/main/java/org/kie/kogito/serverless/workflow/rpc/RPCWorkItemHandler.java b/kogito-serverless-workflow/kogito-serverless-workflow-grpc-runtime/src/main/java/org/kie/kogito/serverless/workflow/rpc/RPCWorkItemHandler.java index 8fcd5bb834e..8c7265a9bea 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-grpc-runtime/src/main/java/org/kie/kogito/serverless/workflow/rpc/RPCWorkItemHandler.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-grpc-runtime/src/main/java/org/kie/kogito/serverless/workflow/rpc/RPCWorkItemHandler.java @@ -33,7 +33,7 @@ import java.util.function.UnaryOperator; import java.util.stream.Collectors; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.JsonObjectUtils; import org.kie.kogito.serverless.workflow.SWFConstants; import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-python-runtime/src/main/java/org/kie/kogito/serverless/workflow/python/PythonScriptWorkItemHandler.java b/kogito-serverless-workflow/kogito-serverless-workflow-python-runtime/src/main/java/org/kie/kogito/serverless/workflow/python/PythonScriptWorkItemHandler.java index 453cbe2bf37..729a716d3fb 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-python-runtime/src/main/java/org/kie/kogito/serverless/workflow/python/PythonScriptWorkItemHandler.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-python-runtime/src/main/java/org/kie/kogito/serverless/workflow/python/PythonScriptWorkItemHandler.java @@ -21,7 +21,7 @@ import java.util.Collections; import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler; import jep.Interpreter; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/ServiceWorkItemHandler.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/ServiceWorkItemHandler.java index d303b68cf0f..40dd5d551d4 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/ServiceWorkItemHandler.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/ServiceWorkItemHandler.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.Set; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import static org.kie.kogito.serverless.workflow.SWFConstants.CONTENT_DATA; import static org.kie.kogito.serverless.workflow.SWFConstants.MODEL_WORKFLOW_VAR; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java index 557cb6c86dd..6c08732ec69 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java @@ -21,25 +21,29 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.jackson.utils.JsonObjectUtils; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class WorkflowWorkItemHandler implements KogitoWorkItemHandler { +public abstract class WorkflowWorkItemHandler extends DefaultKogitoWorkItemHandler { private static final Logger logger = LoggerFactory.getLogger(WorkflowWorkItemHandler.class); @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Map parameters = new HashMap<>(workItem.getParameters()); parameters.remove(SWFConstants.MODEL_WORKFLOW_VAR); logger.debug("Workflow workitem {} will be invoked with parameters {}", workItem.getName(), parameters); - manager.completeWorkItem(workItem.getStringId(), Collections.singletonMap("Result", - JsonObjectUtils.fromValue(internalExecute(workItem, parameters)))); + + Map params = Collections.singletonMap("Result", JsonObjectUtils.fromValue(internalExecute(workItem, parameters))); + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), params)); } protected abstract Object internalExecute(KogitoWorkItem workItem, Map parameters); @@ -56,9 +60,4 @@ protected static V buildBody(Map params, Class clazz) { return value; } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - // abort does nothing - } - } diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigSuppliedWorkItemResolver.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigSuppliedWorkItemResolver.java index 1f5c5c70535..6f407af611c 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigSuppliedWorkItemResolver.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigSuppliedWorkItemResolver.java @@ -20,7 +20,7 @@ import java.util.function.UnaryOperator; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; public class ConfigSuppliedWorkItemResolver extends ConfigWorkItemResolver { diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigWorkItemResolver.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigWorkItemResolver.java index 55129a32b06..875c9e3af6f 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigWorkItemResolver.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ConfigWorkItemResolver.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.serverless.workflow.workitemparams; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.process.workitems.impl.WorkItemParamResolver; import org.kie.kogito.serverless.workflow.utils.ConfigResolverHolder; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionParametersFactory.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionParametersFactory.java index e09687eceda..8ba9088a9d2 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionParametersFactory.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionParametersFactory.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.JsonObjectUtils; import org.kie.kogito.process.workitems.WorkParametersFactory; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionWorkItemResolver.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionWorkItemResolver.java index 98a9e78de0b..1a334f1ad89 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionWorkItemResolver.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ExpressionWorkItemResolver.java @@ -20,7 +20,7 @@ import org.jbpm.util.ContextFactory; import org.kie.kogito.internal.process.runtime.KogitoProcessContext; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.JsonNodeVisitor; import org.kie.kogito.jackson.utils.JsonObjectUtils; import org.kie.kogito.process.expr.Expression; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/JsonNodeResolver.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/JsonNodeResolver.java index d07f37f68b0..1bd1799e083 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/JsonNodeResolver.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/JsonNodeResolver.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.serverless.workflow.workitemparams; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import com.fasterxml.jackson.databind.JsonNode; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ObjectResolver.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ObjectResolver.java index bb91f74286d..c2c421ef8de 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ObjectResolver.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/workitemparams/ObjectResolver.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.serverless.workflow.workitemparams; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.JsonObjectUtils; public class ObjectResolver extends ExpressionWorkItemResolver { diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJqResolverTest.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJqResolverTest.java index 86dd9f97f1e..80cbe070f14 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJqResolverTest.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJqResolverTest.java @@ -27,7 +27,7 @@ import org.kie.api.definition.process.Process; import org.kie.api.runtime.process.WorkflowProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.ObjectMapperFactory; import org.kie.kogito.serverless.workflow.workitemparams.JsonNodeResolver; import org.kie.kogito.serverless.workflow.workitemparams.ObjectResolver; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJsonPathResolverTest.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJsonPathResolverTest.java index e88c9f40efc..fc406248c30 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJsonPathResolverTest.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/test/java/org/kie/kogito/serverless/workflow/JsonNodeJsonPathResolverTest.java @@ -26,7 +26,7 @@ import org.kie.api.definition.process.Process; import org.kie.api.runtime.process.WorkflowProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.jackson.utils.ObjectMapperFactory; import org.kie.kogito.serverless.workflow.workitemparams.JsonNodeResolver; import org.kie.kogito.serverless.workflow.workitemparams.ObjectResolver; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/RestWorkItemHandler.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/RestWorkItemHandler.java index 6ef7cfb899f..48545be05e1 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/RestWorkItemHandler.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/RestWorkItemHandler.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -37,10 +38,12 @@ import org.jbpm.workflow.core.node.WorkItemNode; import org.jbpm.workflow.instance.NodeInstance; import org.jbpm.workflow.instance.node.WorkItemNodeInstance; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kogito.workitem.rest.auth.ApiKeyAuthDecorator; import org.kogito.workitem.rest.auth.AuthDecorator; import org.kogito.workitem.rest.auth.BasicAuthDecorator; @@ -68,7 +71,7 @@ import static org.kogito.workitem.rest.RestWorkItemHandlerUtils.getClassParam; import static org.kogito.workitem.rest.RestWorkItemHandlerUtils.getParam; -public class RestWorkItemHandler implements KogitoWorkItemHandler { +public class RestWorkItemHandler extends DefaultKogitoWorkItemHandler { public static final String REST_TASK_TYPE = "Rest"; public static final String PROTOCOL = "Protocol"; @@ -114,7 +117,7 @@ public RestWorkItemHandler(WebClient httpClient, WebClient httpsClient) { } @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Class targetInfo = getTargetInfo(workItem); logger.debug("Using target {}", targetInfo); //retrieving parameters @@ -188,7 +191,8 @@ public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manag if (statusCode < 200 || statusCode >= 300) { throw new WorkItemExecutionException(Integer.toString(statusCode), "Request for endpoint " + endPoint + " failed with message: " + response.statusMessage()); } - manager.completeWorkItem(workItem.getStringId(), Collections.singletonMap(RESULT, resultHandler.apply(response, targetInfo))); + + return Optional.of(this.workItemLifeCycle.newTransition("complete", workItem.getPhaseStatus(), Collections.singletonMap(RESULT, resultHandler.apply(response, targetInfo)))); } private static HttpResponse sendJson(HttpRequest request, Object body, Duration requestTimeout) { @@ -236,8 +240,4 @@ private Class getType(KogitoWorkItem workItem, String varName) { return null; } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - // rest item handler does not support abort - } } diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/ApiKeyAuthDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/ApiKeyAuthDecorator.java index 467439b8a1c..8166d77c416 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/ApiKeyAuthDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/ApiKeyAuthDecorator.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BasicAuthDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BasicAuthDecorator.java index 66066d8f735..b5d05fd9de3 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BasicAuthDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BasicAuthDecorator.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BearerTokenAuthDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BearerTokenAuthDecorator.java index 2dd2e75b873..47f2bd95f09 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BearerTokenAuthDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/BearerTokenAuthDecorator.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/OAuth2AuthDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/OAuth2AuthDecorator.java index de7c3c6d5c8..0e2f921daf6 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/OAuth2AuthDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/auth/OAuth2AuthDecorator.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/AbstractParamsDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/AbstractParamsDecorator.java index 6804c92ef71..c88916322e6 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/AbstractParamsDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/AbstractParamsDecorator.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.Map.Entry; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/HeaderMetadataDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/HeaderMetadataDecorator.java index 3d284e88713..0d6d19bffed 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/HeaderMetadataDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/HeaderMetadataDecorator.java @@ -21,7 +21,7 @@ import java.util.Map; import org.kie.kogito.event.cloudevents.extension.ProcessMeta; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/RequestDecorator.java b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/RequestDecorator.java index f1b89c156a2..b1055b6cc52 100644 --- a/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/RequestDecorator.java +++ b/kogito-workitems/kogito-rest-workitem/src/main/java/org/kogito/workitem/rest/decorators/RequestDecorator.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/RestWorkItemHandlerTest.java b/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/RestWorkItemHandlerTest.java index 547f03e3516..a67ddb814d0 100644 --- a/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/RestWorkItemHandlerTest.java +++ b/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/RestWorkItemHandlerTest.java @@ -34,7 +34,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kie.kogito.jackson.utils.ObjectMapperFactory; import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; import org.kogito.workitem.rest.bodybuilders.DefaultWorkItemHandlerBodyBuilder; @@ -96,9 +97,6 @@ public class RestWorkItemHandlerTest { @Mock private WorkItemNode node; - @Captor - private ArgumentCaptor> argCaptor; - @Captor private ArgumentCaptor> bodyCaptor; @@ -173,9 +171,10 @@ public void testGetRestTaskHandler() { parameters.put(RestWorkItemHandler.METHOD, "GET"); parameters.put(RestWorkItemHandler.CONTENT_DATA, workflowData); - handler.executeWorkItem(workItem, manager); + WorkItemTransition transition = handler.startingTransition(parameters); + workItem.setPhaseStatus("Activated"); - assertResult(manager, argCaptor); + assertResult(handler.activateWorkItemHandler(manager, handler, workItem, transition)); } @Test @@ -186,11 +185,10 @@ public void testEmptyGet() { when(ioSpecification.getOutputMappingBySources()).thenReturn(Collections.singletonMap(RestWorkItemHandler.RESULT, DEFAULT_WORKFLOW_VAR)); - handler.executeWorkItem(workItem, manager); + Optional transition = handler.transitionToPhase(manager, workItem, handler.startingTransition(parameters)); - verify(manager).completeWorkItem(anyString(), argCaptor.capture()); - Map results = argCaptor.getValue(); - assertThat(results).hasSize(1); + assertThat(transition).isPresent(); + assertThat(transition.get().data()).hasSize(1); } @Test @@ -200,14 +198,13 @@ public void testParametersPostRestTaskHandler() { parameters.put(RestWorkItemHandler.METHOD, "POST"); parameters.put(BODY_BUILDER, new DefaultWorkItemHandlerBodyBuilder()); - handler.executeWorkItem(workItem, manager); + assertResult(handler.transitionToPhase(manager, workItem, handler.startingTransition(parameters))); verify(request).sendJsonAndAwait(bodyCaptor.capture()); Map bodyMap = bodyCaptor.getValue(); assertThat(bodyMap).containsEntry("id", 26) .containsEntry("name", "pepe"); - assertResult(manager, argCaptor); } @Test @@ -216,7 +213,7 @@ public void testContentDataPostRestTaskHandler() { parameters.put(BODY_BUILDER, new DefaultWorkItemHandlerBodyBuilder()); parameters.put(RestWorkItemHandler.CONTENT_DATA, workflowData); - handler.executeWorkItem(workItem, manager); + assertResult(handler.transitionToPhase(manager, workItem, handler.startingTransition(parameters))); ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(ObjectNode.class); verify(request).sendJsonAndAwait(bodyCaptor.capture()); @@ -224,7 +221,6 @@ public void testContentDataPostRestTaskHandler() { assertThat(bodyMap.get("id").asInt()).isEqualTo(26); assertThat(bodyMap.get("name").asText()).isEqualTo("pepe"); - assertResult(manager, argCaptor); } @Test @@ -250,7 +246,7 @@ private void testParametersPostWithCustomParam(String bodyBuilderClass) { parameters.put(customParameter, workflowData); Optional.ofNullable(bodyBuilderClass).ifPresent(builder -> parameters.put(BODY_BUILDER, builder)); - handler.executeWorkItem(workItem, manager); + assertResult(handler.transitionToPhase(manager, workItem, handler.startingTransition(parameters))); verify(request).sendJsonAndAwait(bodyCaptor.capture()); @@ -260,7 +256,6 @@ private void testParametersPostWithCustomParam(String bodyBuilderClass) { //assert the evaluated expression with a process variable .containsEntry(customParameter, workflowData); - assertResult(manager, argCaptor); } @Test @@ -268,7 +263,7 @@ public void testContentPostRestTaskHandler() { parameters.put(RestWorkItemHandler.METHOD, "POST"); parameters.put(RestWorkItemHandler.CONTENT_DATA, workflowData); - handler.executeWorkItem(workItem, manager); + assertResult(handler.transitionToPhase(manager, workItem, handler.startingTransition(parameters))); ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(ObjectNode.class); verify(request).sendJsonAndAwait(bodyCaptor.capture()); @@ -276,14 +271,11 @@ public void testContentPostRestTaskHandler() { assertThat(bodyMap.get("id").asInt()).isEqualTo(26); assertThat(bodyMap.get("name").asText()).isEqualTo("pepe"); - assertResult(manager, argCaptor); } - public void assertResult(KogitoWorkItemManager manager, ArgumentCaptor> argCaptor) { - verify(manager).completeWorkItem(anyString(), argCaptor.capture()); - Map results = argCaptor.getValue(); - assertThat(results).hasSize(1) - .containsKey(RestWorkItemHandler.RESULT); + public void assertResult(Optional transition) { + Map results = transition.get().data(); + assertThat(results).hasSize(1).containsKey(RestWorkItemHandler.RESULT); Object result = results.get(RestWorkItemHandler.RESULT); assertThat(result).isInstanceOf(ObjectNode.class); assertThat(((ObjectNode) result).get("num").asInt()).isOne(); diff --git a/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/decorators/ParamsDecoratorTest.java b/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/decorators/ParamsDecoratorTest.java index 72f749d79d9..0b9a6d73923 100644 --- a/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/decorators/ParamsDecoratorTest.java +++ b/kogito-workitems/kogito-rest-workitem/src/test/java/org/kogito/workitem/rest/decorators/ParamsDecoratorTest.java @@ -23,7 +23,7 @@ import java.util.Map; import org.junit.jupiter.api.Test; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/quarkus/addons/camel/runtime/src/main/java/org/kie/kogito/addons/quarkus/camel/runtime/CamelCustomWorkItemHandler.java b/quarkus/addons/camel/runtime/src/main/java/org/kie/kogito/addons/quarkus/camel/runtime/CamelCustomWorkItemHandler.java index e61efe10e3c..1e45a536c0f 100644 --- a/quarkus/addons/camel/runtime/src/main/java/org/kie/kogito/addons/quarkus/camel/runtime/CamelCustomWorkItemHandler.java +++ b/quarkus/addons/camel/runtime/src/main/java/org/kie/kogito/addons/quarkus/camel/runtime/CamelCustomWorkItemHandler.java @@ -23,7 +23,7 @@ import org.apache.camel.CamelContext; import org.apache.camel.ProducerTemplate; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/CloudEventKnativeParamsDecorator.java b/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/CloudEventKnativeParamsDecorator.java index ac10993ce60..7efcecd2e50 100644 --- a/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/CloudEventKnativeParamsDecorator.java +++ b/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/CloudEventKnativeParamsDecorator.java @@ -21,7 +21,7 @@ import java.util.Map; import org.kie.kogito.event.cloudevents.utils.CloudEventUtils; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kogito.workitem.rest.decorators.ParamsDecorator; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/KnativeWorkItemHandler.java b/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/KnativeWorkItemHandler.java index ac48d1cbcc3..a817e0d726e 100644 --- a/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/KnativeWorkItemHandler.java +++ b/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/KnativeWorkItemHandler.java @@ -20,12 +20,15 @@ import java.net.URI; import java.util.Map; +import java.util.Optional; import org.kie.kogito.addons.k8s.resource.catalog.KubernetesServiceCatalog; import org.kie.kogito.addons.k8s.resource.catalog.KubernetesServiceCatalogKey; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; import org.kogito.workitem.rest.RestWorkItemHandler; import io.vertx.mutiny.ext.web.client.WebClient; @@ -56,10 +59,11 @@ public KnativeWorkItemHandler(WebClient httpClient, WebClient httpsClient, Kuber } @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { Map parameters = workItem.getParameters(); parameters.put(RestWorkItemHandler.URL, getUrl(parameters)); - super.executeWorkItem(workItem, manager); + + return super.activateWorkItemHandler(manager, handler, workItem, transition); } private String getUrl(Map parameters) { diff --git a/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/PlainJsonKnativeParamsDecorator.java b/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/PlainJsonKnativeParamsDecorator.java index 23fe01bc287..03d335934fb 100644 --- a/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/PlainJsonKnativeParamsDecorator.java +++ b/quarkus/addons/knative/serving/runtime/src/main/java/org/kie/kogito/addons/quarkus/knative/serving/customfunctions/PlainJsonKnativeParamsDecorator.java @@ -22,7 +22,7 @@ import java.util.Map; import org.kie.kogito.event.cloudevents.utils.CloudEventUtils; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kogito.workitem.rest.decorators.ParamsDecorator; import io.vertx.mutiny.ext.web.client.HttpRequest; diff --git a/quarkus/addons/persistence/kafka/runtime/src/test/java/org/kie/kogito/persistence/kafka/KafkaProcessInstancesIT.java b/quarkus/addons/persistence/kafka/runtime/src/test/java/org/kie/kogito/persistence/kafka/KafkaProcessInstancesIT.java index 6f1773b46ef..29f167ddceb 100644 --- a/quarkus/addons/persistence/kafka/runtime/src/test/java/org/kie/kogito/persistence/kafka/KafkaProcessInstancesIT.java +++ b/quarkus/addons/persistence/kafka/runtime/src/test/java/org/kie/kogito/persistence/kafka/KafkaProcessInstancesIT.java @@ -41,6 +41,9 @@ import org.kie.kogito.process.WorkItem; import org.kie.kogito.process.bpmn2.BpmnProcess; import org.kie.kogito.process.bpmn2.BpmnVariables; +import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; +import org.kie.kogito.process.impl.StaticProcessConfig; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; import org.kie.kogito.testcontainers.KogitoKafkaContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -112,7 +115,9 @@ private void awaitTillSize(ProcessInstances instances, int size) { @Test void testFindByIdReadMode() { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask-Script.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask-Script.bpmn2")).get(0); listener.setKafkaStreams(createStreams()); process.setProcessInstancesFactory(factory); @@ -150,7 +155,9 @@ void testFindByIdReadMode() { @Test void testValuesReadMode() { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); listener.setKafkaStreams(createStreams()); process.setProcessInstancesFactory(factory); process.configure(); @@ -173,7 +180,9 @@ void testValuesReadMode() { @Test void testBasicFlow() { - BpmnProcess process = BpmnProcess.from(new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); + StaticProcessConfig config = new StaticProcessConfig(); + ((DefaultWorkItemHandlerConfig) config.workItemHandlers()).register("Human Task", new DefaultKogitoWorkItemHandler()); + BpmnProcess process = BpmnProcess.from(config, new ClassPathResource("BPMN2-UserTask.bpmn2")).get(0); listener.setKafkaStreams(createStreams()); process.setProcessInstancesFactory(factory); process.configure(); diff --git a/quarkus/addons/python/runtime/src/main/java/org/kie/kogito/quarkus/serverless/workflow/python/PythonWorkItemHandlerConfig.java b/quarkus/addons/python/runtime/src/main/java/org/kie/kogito/quarkus/serverless/workflow/python/PythonWorkItemHandlerConfig.java index 08d4a34e620..81685985ab1 100644 --- a/quarkus/addons/python/runtime/src/main/java/org/kie/kogito/quarkus/serverless/workflow/python/PythonWorkItemHandlerConfig.java +++ b/quarkus/addons/python/runtime/src/main/java/org/kie/kogito/quarkus/serverless/workflow/python/PythonWorkItemHandlerConfig.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.quarkus.serverless.workflow.python; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; import org.kie.kogito.process.impl.CachedWorkItemHandlerConfig; import org.kie.kogito.serverless.workflow.python.PythonScriptWorkItemHandler; import org.kie.kogito.serverless.workflow.python.PythonServiceWorkItemHandler; diff --git a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidLifeCyclePhaseExceptionMapper.java b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidLifeCyclePhaseExceptionMapper.java index 2f9e0f6a2a2..82341b6eecd 100644 --- a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidLifeCyclePhaseExceptionMapper.java +++ b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidLifeCyclePhaseExceptionMapper.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.resource.exceptions; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; +import org.kie.kogito.internal.process.workitem.InvalidLifeCyclePhaseException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.Provider; diff --git a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidTransitionExceptionMapper.java b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidTransitionExceptionMapper.java index c5d8785ab6c..ff04b15e15f 100644 --- a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidTransitionExceptionMapper.java +++ b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/InvalidTransitionExceptionMapper.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.resource.exceptions; -import org.kie.kogito.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.Provider; diff --git a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/NotAuthorizedExceptionMapper.java b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/NotAuthorizedExceptionMapper.java index 99b030fc07e..030783daa6e 100644 --- a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/NotAuthorizedExceptionMapper.java +++ b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/NotAuthorizedExceptionMapper.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.resource.exceptions; -import org.kie.kogito.process.workitem.NotAuthorizedException; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.Provider; diff --git a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemExecutionExceptionMapper.java b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemExecutionExceptionMapper.java index 53f97d5163f..1ffb619cebb 100644 --- a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemExecutionExceptionMapper.java +++ b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemExecutionExceptionMapper.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.resource.exceptions; -import org.kie.kogito.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.Provider; diff --git a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemNotFoundExceptionMapper.java b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemNotFoundExceptionMapper.java index 1d24e26b21a..a0d0731dcc3 100644 --- a/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemNotFoundExceptionMapper.java +++ b/quarkus/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/WorkItemNotFoundExceptionMapper.java @@ -18,7 +18,7 @@ */ package org.kie.kogito.resource.exceptions; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.Provider; diff --git a/quarkus/addons/task-management/runtime/src/main/java/org/kie/kogito/task/management/TaskManagementResource.java b/quarkus/addons/task-management/runtime/src/main/java/org/kie/kogito/task/management/TaskManagementResource.java index 923933b1865..538d1e3b435 100644 --- a/quarkus/addons/task-management/runtime/src/main/java/org/kie/kogito/task/management/TaskManagementResource.java +++ b/quarkus/addons/task-management/runtime/src/main/java/org/kie/kogito/task/management/TaskManagementResource.java @@ -20,9 +20,9 @@ import java.util.List; +import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.Processes; -import org.kie.kogito.process.workitem.Policies; import org.kie.kogito.task.management.service.TaskInfo; import org.kie.kogito.task.management.service.TaskManagementOperations; import org.kie.kogito.task.management.service.TaskManagementService; @@ -66,7 +66,7 @@ public Response updateTask(@PathParam("processId") String processId, @QueryParam("user") final String user, @QueryParam("group") final List groups, TaskInfo taskInfo) { - taskService.updateTask(processId, processInstanceId, taskId, taskInfo, true, Policies.of(user, groups)); + taskService.updateTask(processId, processInstanceId, taskId, taskInfo, true, SecurityPolicy.of(user, groups)); return Response.ok().build(); } @@ -80,7 +80,7 @@ public TaskInfo partialUpdateTask(@PathParam("processId") String processId, @QueryParam("user") final String user, @QueryParam("group") final List groups, TaskInfo taskInfo) { - return taskService.updateTask(processId, processInstanceId, taskId, taskInfo, false, Policies.of(user, groups)); + return taskService.updateTask(processId, processInstanceId, taskId, taskInfo, false, SecurityPolicy.of(user, groups)); } @GET @@ -92,6 +92,6 @@ public TaskInfo getTask(@PathParam("processId") String processId, @PathParam("taskId") String taskId, @QueryParam("user") final String user, @QueryParam("group") final List groups) { - return taskService.getTask(processId, processInstanceId, taskId, Policies.of(user, groups)); + return taskService.getTask(processId, processInstanceId, taskId, SecurityPolicy.of(user, groups)); } } diff --git a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-integration-test/src/test/java/org/acme/StatefulProcessResourceTest.java b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-integration-test/src/test/java/org/acme/StatefulProcessResourceTest.java index 0ec92c1cca7..69cdcd7b147 100644 --- a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-integration-test/src/test/java/org/acme/StatefulProcessResourceTest.java +++ b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-integration-test/src/test/java/org/acme/StatefulProcessResourceTest.java @@ -22,10 +22,15 @@ import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.kie.kogito.incubation.application.AppRoot; -import org.kie.kogito.incubation.common.*; -import org.kie.kogito.incubation.processes.*; +import org.kie.kogito.incubation.common.EmptyDataContext; +import org.kie.kogito.incubation.common.ExtendedDataContext; +import org.kie.kogito.incubation.common.MapDataContext; +import org.kie.kogito.incubation.processes.ProcessIds; +import org.kie.kogito.incubation.processes.ProcessInstanceId; +import org.kie.kogito.incubation.processes.TaskInstanceId; import org.kie.kogito.incubation.processes.services.StatefulProcessService; import org.kie.kogito.incubation.processes.services.contexts.Policy; import org.kie.kogito.incubation.processes.services.contexts.ProcessMetaDataContext; @@ -151,6 +156,7 @@ public void abortProcess() throws JsonProcessingException { } @Test + @Disabled("Revisited after ht endpoints") public void completeTask() throws JsonProcessingException { /// /processes/approvals var id = appRoot.get(ProcessIds.class).get("approvals"); @@ -188,6 +194,7 @@ public void completeTask() throws JsonProcessingException { } @Test + @Disabled("Revisited after ht endpoints") public void completeProcess() throws JsonProcessingException { /// /processes/approvals var id = appRoot.get(ProcessIds.class).get("approvals"); @@ -280,6 +287,7 @@ public void signalTaskProcess() { } @Test + @Disabled("Revisited after ht endpoints") public void completeProcessTask() { var id = appRoot.get(ProcessIds.class).get("signal"); MapDataContext dc = MapDataContext.create(); diff --git a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml index 85925dcfc61..c93fe7c1cd3 100644 --- a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml +++ b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml @@ -53,7 +53,8 @@ org.kie.kogito - jbpm-bpmn2 + jbpm-deps-group-bpmn2-compiler + pom org.eclipse.microprofile.openapi diff --git a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/src/main/java/org/kie/kogito/core/process/incubation/quarkus/support/HumanTaskServiceImpl.java b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/src/main/java/org/kie/kogito/core/process/incubation/quarkus/support/HumanTaskServiceImpl.java index d1f89d6d86d..3cd0123ffa4 100644 --- a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/src/main/java/org/kie/kogito/core/process/incubation/quarkus/support/HumanTaskServiceImpl.java +++ b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/src/main/java/org/kie/kogito/core/process/incubation/quarkus/support/HumanTaskServiceImpl.java @@ -25,22 +25,33 @@ import java.util.function.Function; import java.util.stream.Collectors; -import org.jbpm.process.instance.impl.humantask.HumanTaskHelper; import org.jbpm.workflow.core.node.HumanTaskNode; import org.kie.kogito.Application; import org.kie.kogito.MappableToModel; import org.kie.kogito.Model; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; -import org.kie.kogito.incubation.common.*; -import org.kie.kogito.incubation.processes.*; +import org.kie.kogito.incubation.common.DataContext; +import org.kie.kogito.incubation.common.EmptyDataContext; +import org.kie.kogito.incubation.common.ExtendedDataContext; +import org.kie.kogito.incubation.common.LocalId; +import org.kie.kogito.incubation.common.MapDataContext; +import org.kie.kogito.incubation.common.MetaDataContext; +import org.kie.kogito.incubation.processes.LocalProcessId; +import org.kie.kogito.incubation.processes.ProcessIdParser; +import org.kie.kogito.incubation.processes.ProcessInstanceId; +import org.kie.kogito.incubation.processes.TaskId; +import org.kie.kogito.incubation.processes.TaskIds; +import org.kie.kogito.incubation.processes.TaskInstanceId; import org.kie.kogito.incubation.processes.services.contexts.Policy; import org.kie.kogito.incubation.processes.services.contexts.ProcessMetaDataContext; import org.kie.kogito.incubation.processes.services.contexts.TaskMetaDataContext; import org.kie.kogito.incubation.processes.services.humantask.HumanTaskService; import org.kie.kogito.internal.process.runtime.KogitoNode; -import org.kie.kogito.process.*; import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessService; +import org.kie.kogito.process.Processes; +import org.kie.kogito.process.WorkItem; import org.kie.kogito.services.uow.UnitOfWorkExecutor; class HumanTaskServiceImpl implements HumanTaskService { @@ -62,17 +73,14 @@ private Process> parseProcess(LocalProcessId pid) { @Override public ExtendedDataContext get(LocalId id, MetaDataContext meta) { TaskMetaDataContext metaCtx = meta.as(TaskMetaDataContext.class); - SecurityPolicy securityPolicy = convertPolicyObject(metaCtx.policy()); + try { TaskIds taskIds = ProcessIdParser.select(id, TaskIds.class); // /tasks ProcessInstanceId instanceId = taskIds.processInstanceId(); Process> process = parseProcess(instanceId.processId()); String processInstanceIdString = instanceId.processInstanceId(); - List tasks = svc.getTasks( - process, - processInstanceIdString, - securityPolicy).orElseThrow().stream() + List tasks = svc.getWorkItems(process, processInstanceIdString, convertPolicyObject(metaCtx.policy())).orElseThrow().stream() .map(wi -> taskIds.get(wi.getName()).instances().get(wi.getId()).asLocalUri().path()) .collect(Collectors.toList()); MapDataContext mdc = MapDataContext.create(); @@ -87,12 +95,11 @@ public ExtendedDataContext get(LocalId id, MetaDataContext meta) { String taskInstanceIdString = taskInstanceId.taskInstanceId(); String processInstanceIdString = instanceId.processInstanceId(); - WorkItem workItem = - svc.getTask( - process, - processInstanceIdString, - taskInstanceIdString, - securityPolicy, Function.identity()).orElseThrow(() -> new IllegalArgumentException("Cannot find ID " + id.asLocalUri().path())); + WorkItem workItem = svc.getWorkItem( + process, + processInstanceIdString, + taskInstanceIdString, + convertPolicyObject(metaCtx.policy()), Function.identity()).orElseThrow(() -> new IllegalArgumentException("Cannot find ID " + id.asLocalUri().path())); return ExtendedDataContext.ofData(MapDataContext.of(workItem.getResults())); } } @@ -105,10 +112,8 @@ public ExtendedDataContext create(LocalId id, DataContext dataContext) { ExtendedDataContext edc = dataContext.as(ExtendedDataContext.class); TaskMetaDataContext mdc = edc.meta().as(TaskMetaDataContext.class); - SecurityPolicy securityPolicy = convertPolicyObject(mdc.policy()); - WorkItem workItem = svc.signalTask(process, instanceId.processInstanceId(), taskId.taskId(), securityPolicy) - .orElseThrow(); + WorkItem workItem = svc.signalWorkItem(process, instanceId.processInstanceId(), taskId.taskId(), convertPolicyObject(mdc.policy())).orElseThrow(); return ExtendedDataContext.of(ProcessMetaDataContext.of(taskId), MapDataContext.from(workItem)); } @@ -134,7 +139,6 @@ public ExtendedDataContext complete(LocalId processId, DataContext dataContext) public ExtendedDataContext transition(LocalId id, DataContext dataContext) { ExtendedDataContext edc = dataContext.as(ExtendedDataContext.class); TaskMetaDataContext mdc = edc.meta().as(TaskMetaDataContext.class); - SecurityPolicy securityPolicy = convertPolicyObject(mdc.policy()); String phase = mdc.phase(); Objects.requireNonNull(phase, "Phase must be specified"); @@ -159,12 +163,12 @@ public ExtendedDataContext transition(LocalId id, DataContext dataContext) { MappableToModel model = process.createModel(); model.fromMap(map); - Model result = svc.taskTransition( + Model result = svc.transitionWorkItem( process, processInstanceIdString, taskInstanceIdString, phase, - securityPolicy, + convertPolicyObject(mdc.policy()), model) .orElseThrow(); @@ -175,7 +179,6 @@ public ExtendedDataContext transition(LocalId id, DataContext dataContext) { public ExtendedDataContext update(LocalId id, DataContext dataContext) { ExtendedDataContext edc = dataContext.as(ExtendedDataContext.class); TaskMetaDataContext mdc = edc.meta().as(TaskMetaDataContext.class); - SecurityPolicy securityPolicy = convertPolicyObject(mdc.policy()); TaskInstanceId taskInstanceId = ProcessIdParser.select(id, TaskInstanceId.class); @@ -192,9 +195,10 @@ public ExtendedDataContext update(LocalId id, DataContext dataContext) { .instances() .findById(processInstanceIdString) .map(pi -> { - pi.updateWorkItem( - taskInstanceIdString, - wi -> HumanTaskHelper.updateContent(wi, map), securityPolicy); + pi.updateWorkItem(taskInstanceIdString, wi -> { + wi.setOutputs(map); + return null; + }, convertPolicyObject(mdc.policy())); return pi.variables().toModel(); })) .orElseThrow().toMap(); diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/java/org/kie/kogito/workflows/services/RPCCustomWorkItemHandler.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/java/org/kie/kogito/workflows/services/RPCCustomWorkItemHandler.java index b49a2765081..ed00e4ebf53 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/java/org/kie/kogito/workflows/services/RPCCustomWorkItemHandler.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/java/org/kie/kogito/workflows/services/RPCCustomWorkItemHandler.java @@ -20,7 +20,7 @@ import java.util.Map; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler; import jakarta.enterprise.context.ApplicationScoped; diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java index 11cab0d9f01..596f8e14b68 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java @@ -30,7 +30,7 @@ public class CompensationRestIT { @Test - public void testErrorRest() { + public void testErrorRest1() { given() .contentType(ContentType.JSON) .accept(ContentType.JSON) @@ -39,6 +39,10 @@ public void testErrorRest() { .then() .statusCode(201) .body("workflowdata.compensated", is(true)); + } + + @Test + public void testErrorRest2() { given() .contentType(ContentType.JSON) .accept(ContentType.JSON) @@ -48,6 +52,11 @@ public void testErrorRest() { .statusCode(201) .body("workflowdata.compensated", is(true)) .body("workflowdata.isEven", is(false)); + + } + + @Test + public void testErrorRest3() { given() .contentType(ContentType.JSON) .accept(ContentType.JSON) diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java index db3799b1a88..6a021fdaa8c 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/serverless/workflow/openapi/OpenApiWorkItemHandler.java @@ -28,9 +28,9 @@ import org.jbpm.util.ContextFactory; import org.jbpm.workflow.core.WorkflowProcess; import org.kie.kogito.event.cloudevents.extension.ProcessMeta; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; import org.kie.kogito.process.expr.ExpressionHandlerFactory; -import org.kie.kogito.process.workitem.WorkItemExecutionException; import org.kie.kogito.serverless.workflow.SWFConstants; import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler; diff --git a/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java b/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java index 0df5e9c7fed..9ed746de80a 100644 --- a/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java +++ b/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java @@ -18,21 +18,25 @@ */ package org.kie.kogito.wih; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import java.util.Collections; +import java.util.Optional; -import static java.util.Collections.emptyMap; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public class CustomWorkItemHandler implements KogitoWorkItemHandler { +public class CustomWorkItemHandler extends DefaultKogitoWorkItemHandler { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.completeWorkItem(workItem.getStringId(), emptyMap()); + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + return Optional.of(handler.completeTransition(workItem.getPhaseStatus(), Collections.emptyMap())); } @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.abortWorkItem(workItem.getStringId()); + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) { + return Optional.of(handler.completeTransition(workItem.getPhaseStatus(), Collections.emptyMap())); } + } diff --git a/quarkus/integration-tests/integration-tests-quarkus-processes/src/main/java/org/acme/CustomTaskWorkItemHandler.java b/quarkus/integration-tests/integration-tests-quarkus-processes/src/main/java/org/acme/CustomTaskWorkItemHandler.java index 5b3f053d15e..d89b0ce4c85 100644 --- a/quarkus/integration-tests/integration-tests-quarkus-processes/src/main/java/org/acme/CustomTaskWorkItemHandler.java +++ b/quarkus/integration-tests/integration-tests-quarkus-processes/src/main/java/org/acme/CustomTaskWorkItemHandler.java @@ -18,21 +18,21 @@ */ package org.acme; +import java.util.Optional; + import org.kie.api.runtime.process.ProcessWorkItemHandlerException; import org.kie.api.runtime.process.ProcessWorkItemHandlerException.HandlingStrategy; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public class CustomTaskWorkItemHandler implements KogitoWorkItemHandler { +public class CustomTaskWorkItemHandler extends DefaultKogitoWorkItemHandler { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { throw new ProcessWorkItemHandlerException("error_handling", HandlingStrategy.COMPLETE, null); } - @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - - } } diff --git a/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/ManagementAddOnIT.java b/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/ManagementAddOnIT.java index 7d474be02aa..95500eb16a4 100644 --- a/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/ManagementAddOnIT.java +++ b/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/ManagementAddOnIT.java @@ -78,8 +78,8 @@ void testGetNodeInstances() { .statusCode(200) .body("$.size()", is(2)) .body("$", hasItems(hasEntry("name", "Hello1"), hasEntry("name", "Hello2"))) - .body("[0].state", is(0)) - .body("[1].state", is(0)); + .body("[0].state", is(1)) + .body("[1].state", is(1)); } @Test diff --git a/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/TaskIT.java b/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/TaskIT.java index b6e9435da81..d5a5513a165 100644 --- a/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/TaskIT.java +++ b/quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/TaskIT.java @@ -20,16 +20,15 @@ import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; import org.acme.travels.Traveller; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.kie.kogito.process.workitem.AttachmentInfo; import org.kie.kogito.task.management.service.TaskInfo; +import org.kie.kogito.usertask.model.AttachmentInfo; import io.quarkus.test.junit.QuarkusIntegrationTest; import io.restassured.RestAssured; @@ -41,7 +40,6 @@ import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchema; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; @QuarkusIntegrationTest @@ -162,6 +160,7 @@ void testSaveTask() { } @Test + @Disabled("Revisited after ht endpoints") void testCommentAndAttachment() { Traveller traveller = new Traveller("pepe", "rubiales", "pepe.rubiales@gmail.com", "Spanish"); @@ -177,7 +176,7 @@ void testCommentAndAttachment() { String taskId = given() .contentType(ContentType.JSON) - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .when() @@ -189,7 +188,7 @@ void testCommentAndAttachment() { final String commentId = given().contentType(ContentType.TEXT) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -203,7 +202,7 @@ void testCommentAndAttachment() { final String commentText = "We have done everything we can"; given().contentType(ContentType.TEXT) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -215,7 +214,7 @@ void testCommentAndAttachment() { assertEquals(commentText, given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -226,7 +225,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -237,7 +236,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -248,7 +247,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -259,7 +258,7 @@ void testCommentAndAttachment() { final String attachmentId = given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -272,7 +271,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -285,7 +284,7 @@ void testCommentAndAttachment() { given().contentType( ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -297,7 +296,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -308,7 +307,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -319,7 +318,7 @@ void testCommentAndAttachment() { given().contentType(ContentType.JSON) .when() - .queryParam("user", "admin") + .queryParam("user", "manager") .queryParam("group", "managers") .pathParam("processId", processId) .pathParam("taskId", taskId) @@ -329,58 +328,6 @@ void testCommentAndAttachment() { .statusCode(404); } - @Test - void testUpdateExcludedUsers() { - Traveller traveller = new Traveller("pepe", "rubiales", "pepe.rubiales@gmail.com", "Spanish"); - - String processId = given() - .contentType(ContentType.JSON) - .when() - .body(Collections.singletonMap("traveller", traveller)) - .post("/approvals") - .then() - .statusCode(201) - .extract() - .path("id"); - - String taskId = given() - .contentType(ContentType.JSON) - .queryParam("user", "admin") - .queryParam("group", "managers") - .pathParam("processId", processId) - .when() - .get("/approvals/{processId}/tasks") - .then() - .statusCode(200) - .extract() - .path("[0].id"); - - Collection excludedUsers = Arrays.asList("Javierito", "Manuel"); - given().contentType(ContentType.JSON) - .when() - .queryParam("user", "admin") - .queryParam("group", "managers") - .pathParam("processId", processId) - .pathParam("taskId", taskId) - .body(Collections.singletonMap("excludedUsers", excludedUsers)) - .patch("/management/processes/approvals/instances/{processId}/tasks/{taskId}") - .then() - .statusCode(200) - .body("excludedUsers", is(excludedUsers)); - - assertEquals(excludedUsers, given().contentType(ContentType.JSON) - .when() - .queryParam("user", "admin") - .queryParam("group", "managers") - .pathParam("processId", processId) - .pathParam("taskId", taskId) - .get("/management/processes/approvals/instances/{processId}/tasks/{taskId}") - .then() - .statusCode(200) - .extract() - .path("excludedUsers")); - } - @Test void testUpdateTaskInfo() { Traveller traveller = new Traveller("pepe", "rubiales", "pepe.rubiales@gmail.com", "Spanish"); @@ -433,13 +380,6 @@ void testUpdateTaskInfo() { .statusCode(200) .extract() .as(ClientTaskInfo.class); - assertEquals(upTaskInfo.getAdminGroups(), downTaskInfo.adminGroups); - assertEquals(upTaskInfo.getAdminUsers(), downTaskInfo.adminUsers); - assertEquals(upTaskInfo.getPotentialGroups(), downTaskInfo.potentialGroups); - assertEquals(upTaskInfo.getPotentialUsers(), downTaskInfo.potentialUsers); - assertEquals(upTaskInfo.getExcludedUsers(), downTaskInfo.excludedUsers); - assertEquals(upTaskInfo.getDescription(), downTaskInfo.description); - assertEquals(upTaskInfo.getPriority(), downTaskInfo.priority); assertEquals(traveller, downTaskInfo.inputParams.traveller); } diff --git a/springboot/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandler.java b/springboot/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandler.java index 49ab414f0ab..d5d5dfa96e4 100644 --- a/springboot/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandler.java +++ b/springboot/addons/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandler.java @@ -18,17 +18,17 @@ */ package org.kie.kogito.resource.exceptions.springboot; -import org.kie.kogito.internal.process.runtime.WorkItemNotFoundException; +import org.kie.kogito.internal.process.workitem.InvalidLifeCyclePhaseException; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; +import org.kie.kogito.internal.process.workitem.WorkItemExecutionException; +import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException; import org.kie.kogito.process.NodeInstanceNotFoundException; import org.kie.kogito.process.NodeNotFoundException; import org.kie.kogito.process.ProcessInstanceDuplicatedException; import org.kie.kogito.process.ProcessInstanceExecutionException; import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.VariableViolationException; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; -import org.kie.kogito.process.workitem.InvalidTransitionException; -import org.kie.kogito.process.workitem.NotAuthorizedException; -import org.kie.kogito.process.workitem.WorkItemExecutionException; import org.kie.kogito.resource.exceptions.BaseExceptionsHandler; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; diff --git a/springboot/addons/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandlerTest.java b/springboot/addons/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandlerTest.java index 808595cd2db..4512a30b7fc 100644 --- a/springboot/addons/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandlerTest.java +++ b/springboot/addons/rest-exception-handler/src/test/java/org/kie/kogito/resource/exceptions/springboot/ExceptionsHandlerTest.java @@ -21,14 +21,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.kie.kogito.internal.process.workitem.InvalidLifeCyclePhaseException; +import org.kie.kogito.internal.process.workitem.InvalidTransitionException; +import org.kie.kogito.internal.process.workitem.NotAuthorizedException; import org.kie.kogito.process.NodeInstanceNotFoundException; import org.kie.kogito.process.ProcessInstanceDuplicatedException; import org.kie.kogito.process.ProcessInstanceExecutionException; import org.kie.kogito.process.ProcessInstanceNotFoundException; import org.kie.kogito.process.VariableViolationException; -import org.kie.kogito.process.workitem.InvalidLifeCyclePhaseException; -import org.kie.kogito.process.workitem.InvalidTransitionException; -import org.kie.kogito.process.workitem.NotAuthorizedException; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpStatus; diff --git a/springboot/addons/task-management/src/main/java/org/kie/kogito/task/management/TaskManagementRestController.java b/springboot/addons/task-management/src/main/java/org/kie/kogito/task/management/TaskManagementRestController.java index 19a0b3fd542..aa82dc81cb4 100644 --- a/springboot/addons/task-management/src/main/java/org/kie/kogito/task/management/TaskManagementRestController.java +++ b/springboot/addons/task-management/src/main/java/org/kie/kogito/task/management/TaskManagementRestController.java @@ -20,9 +20,9 @@ import java.util.List; +import org.kie.kogito.jbpm.usertask.handler.Policies; import org.kie.kogito.process.ProcessConfig; import org.kie.kogito.process.Processes; -import org.kie.kogito.process.workitem.Policies; import org.kie.kogito.task.management.service.TaskInfo; import org.kie.kogito.task.management.service.TaskManagementOperations; import org.kie.kogito.task.management.service.TaskManagementService; diff --git a/springboot/archetype/pom.xml b/springboot/archetype/pom.xml index 42cbd1878e4..de51a35a813 100644 --- a/springboot/archetype/pom.xml +++ b/springboot/archetype/pom.xml @@ -83,11 +83,6 @@ jbpm-with-drools-spring-boot-starter test - - org.jbpm - jbpm-spring-boot-starter - test - org.springframework.boot spring-boot-starter-parent diff --git a/springboot/integration-tests/integration-tests-springboot-decisions-it/pom.xml b/springboot/integration-tests/integration-tests-springboot-decisions-it/pom.xml index 9f08b2b8353..ccfd8d904d3 100644 --- a/springboot/integration-tests/integration-tests-springboot-decisions-it/pom.xml +++ b/springboot/integration-tests/integration-tests-springboot-decisions-it/pom.xml @@ -178,6 +178,7 @@ + diff --git a/springboot/integration-tests/integration-tests-springboot-kafka-it/.gitignore b/springboot/integration-tests/integration-tests-springboot-kafka-it/.gitignore new file mode 100644 index 00000000000..b83d22266ac --- /dev/null +++ b/springboot/integration-tests/integration-tests-springboot-kafka-it/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/springboot/integration-tests/integration-tests-springboot-kafka-it/pom.xml b/springboot/integration-tests/integration-tests-springboot-kafka-it/pom.xml index 690239a1240..890b7513937 100644 --- a/springboot/integration-tests/integration-tests-springboot-kafka-it/pom.xml +++ b/springboot/integration-tests/integration-tests-springboot-kafka-it/pom.xml @@ -149,6 +149,14 @@ + + maven-compiler-plugin + ${version.compiler.plugin} + + ${maven.compiler.release} + + + org.springframework.boot spring-boot-maven-plugin diff --git a/springboot/integration-tests/integration-tests-springboot-processes-it/.gitignore b/springboot/integration-tests/integration-tests-springboot-processes-it/.gitignore new file mode 100644 index 00000000000..b83d22266ac --- /dev/null +++ b/springboot/integration-tests/integration-tests-springboot-processes-it/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java index 25bb26eda06..ac7b72f40d5 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java +++ b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java @@ -81,8 +81,8 @@ void testGetNodeInstances() { .statusCode(200) .body("$.size()", is(2)) .body("$", hasItems(hasEntry("name", "Hello1"), hasEntry("name", "Hello2"))) - .body("[0].state", is(0)) - .body("[1].state", is(0)); + .body("[0].state", is(1)) + .body("[1].state", is(1)); } @Test diff --git a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java index aa6cdab9675..970968e6497 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java +++ b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java @@ -24,8 +24,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.stream.Stream; @@ -33,10 +31,11 @@ import org.acme.travels.Address; import org.acme.travels.Traveller; import org.jbpm.util.JsonSchemaUtil; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.kie.kogito.process.workitem.AttachmentInfo; import org.kie.kogito.task.management.service.TaskInfo; +import org.kie.kogito.usertask.model.AttachmentInfo; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -46,7 +45,6 @@ import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @@ -113,6 +111,7 @@ void testJsonSchemaFiles() { } @Test + @Disabled("Revisited after ht endpoints") void testCommentAndAttachment() { Traveller traveller = new Traveller("pepe", "rubiales", "pepe.rubiales@gmail.com", "Spanish", null); @@ -322,58 +321,6 @@ void testSaveTask() { .path("results.approved")); } - @Test - void testUpdateExcludedUsers() { - Traveller traveller = new Traveller("pepe", "rubiales", "pepe.rubiales@gmail.com", "Spanish", new Address("Alfredo Di Stefano", "Madrid", "28033", "Spain")); - - String processId = given() - .contentType(ContentType.JSON) - .when() - .body(Collections.singletonMap("traveller", traveller)) - .post("/approvals") - .then() - .statusCode(201) - .extract() - .path("id"); - - String taskId = given() - .contentType(ContentType.JSON) - .queryParam("user", "admin") - .queryParam("group", "managers") - .pathParam("processId", processId) - .when() - .get("/approvals/{processId}/tasks") - .then() - .statusCode(200) - .extract() - .path("[0].id"); - - Collection excludedUsers = Arrays.asList("Javierito", "Manuel"); - given().contentType(ContentType.JSON) - .when() - .queryParam("user", "admin") - .queryParam("group", "managers") - .pathParam("processId", processId) - .pathParam("taskId", taskId) - .body(Collections.singletonMap("excludedUsers", excludedUsers)) - .patch("/management/processes/approvals/instances/{processId}/tasks/{taskId}") - .then() - .statusCode(200) - .body("excludedUsers", is(excludedUsers)); - - assertEquals(excludedUsers, given().contentType(ContentType.JSON) - .when() - .queryParam("user", "admin") - .queryParam("group", "managers") - .pathParam("processId", processId) - .pathParam("taskId", taskId) - .get("/management/processes/approvals/instances/{processId}/tasks/{taskId}") - .then() - .statusCode(200) - .extract() - .path("excludedUsers")); - } - @Test void testUpdateTaskInfo() { Traveller traveller = new Traveller("pepe", "rubiales", "pepe.rubiales@gmail.com", "Spanish", new Address("Alfredo Di Stefano", "Madrid", "28033", "Spain")); @@ -425,12 +372,6 @@ void testUpdateTaskInfo() { .statusCode(200) .extract() .as(TaskInfo.class); - assertEquals(upTaskInfo.getAdminGroups(), downTaskInfo.getAdminGroups()); - assertEquals(upTaskInfo.getAdminUsers(), downTaskInfo.getAdminUsers()); - assertEquals(upTaskInfo.getPotentialGroups(), downTaskInfo.getPotentialGroups()); - assertEquals(upTaskInfo.getPotentialUsers(), downTaskInfo.getPotentialUsers()); - assertEquals(upTaskInfo.getExcludedUsers(), downTaskInfo.getExcludedUsers()); - assertEquals(upTaskInfo.getDescription(), downTaskInfo.getDescription()); - assertEquals(upTaskInfo.getPriority(), downTaskInfo.getPriority()); + assertThat(downTaskInfo.getInputParams()).isNotNull(); } } diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-infinispan/.gitignore b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-infinispan/.gitignore index a180e83ba79..c2ca403117d 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-infinispan/.gitignore +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-infinispan/.gitignore @@ -19,3 +19,4 @@ *.bpmn *.wid +/target/ diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/.gitignore b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/.gitignore index a180e83ba79..c2ca403117d 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/.gitignore +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/.gitignore @@ -19,3 +19,4 @@ *.bpmn *.wid +/target/ diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/pom.xml b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/pom.xml index d897aac69d3..f967b626380 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/pom.xml +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/pom.xml @@ -32,6 +32,10 @@ integration-tests-springboot-processes-jdbc Kogito :: Integration Tests :: Spring Boot :: Processes :: Persistence :: JDBC + + false + + org.postgresql @@ -158,4 +162,4 @@ - \ No newline at end of file + diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/.gitignore b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/.gitignore new file mode 100644 index 00000000000..b83d22266ac --- /dev/null +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java index 0df5e9c7fed..e5a1c31c774 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/java/org/kie/kogito/wih/CustomWorkItemHandler.java @@ -18,21 +18,25 @@ */ package org.kie.kogito.wih; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; -import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import java.util.Collections; +import java.util.Optional; -import static java.util.Collections.emptyMap; +import org.kie.kogito.internal.process.workitem.KogitoWorkItem; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager; +import org.kie.kogito.internal.process.workitem.WorkItemTransition; +import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -public class CustomWorkItemHandler implements KogitoWorkItemHandler { +public class CustomWorkItemHandler extends DefaultKogitoWorkItemHandler { @Override - public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.completeWorkItem(workItem.getStringId(), emptyMap()); + public Optional activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return Optional.of(handler.completeTransition(workitem.getPhaseStatus(), Collections.emptyMap())); } @Override - public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { - manager.abortWorkItem(workItem.getStringId()); + public Optional abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workitem, WorkItemTransition transition) { + return Optional.of(handler.abortTransition(workitem.getPhaseStatus())); } + } From 85624b8c5ddd20dcef228a7ed5a684424ffb5c11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:58:27 -0400 Subject: [PATCH 06/15] Bump com.google.protobuf:protobuf-java (#3676) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 3.25.0 to 3.25.5. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.25.0...v3.25.5) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- kogito-build/kogito-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kogito-build/kogito-dependencies-bom/pom.xml b/kogito-build/kogito-dependencies-bom/pom.xml index 760f481e8bb..e0a87af2f99 100644 --- a/kogito-build/kogito-dependencies-bom/pom.xml +++ b/kogito-build/kogito-dependencies-bom/pom.xml @@ -59,7 +59,7 @@ 2.17.2 4.31.0 2.35.1 - 3.25.0 + 3.25.5 2.10.1 From 9205e59389949cecfe043a2139ae7d627c6508fe Mon Sep 17 00:00:00 2001 From: Martin Weiler Date: Tue, 24 Sep 2024 12:04:59 -0600 Subject: [PATCH 07/15] Dispose KieSession after rules execution when using ruleFlowGroup (#3678) * Dispose KieSession after rules execution when using ruleFlowGroup --- .../bpmn2/rule/RuleFlowGroupRuleTypeEngineImpl.java | 3 +++ .../src/test/java/org/jbpm/bpmn2/ActivityTest.java | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/rule/RuleFlowGroupRuleTypeEngineImpl.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/rule/RuleFlowGroupRuleTypeEngineImpl.java index 9896549c8de..f311c042c4f 100644 --- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/rule/RuleFlowGroupRuleTypeEngineImpl.java +++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/rule/RuleFlowGroupRuleTypeEngineImpl.java @@ -73,6 +73,9 @@ public void evaluate(RuleSetNodeInstance rsni, String ruleFlowGroup) { rsni.removeEventListeners(); rsni.retractFacts(kruntime); rsni.triggerCompleted(); + if (kruntime instanceof KieSession) { + ((KieSession) kruntime).dispose(); + } } } diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java index c6887717cee..4a8cca632c9 100755 --- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java +++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java @@ -363,7 +363,6 @@ public void testRuleTask() throws Exception { List list = new ArrayList<>(); kruntime.getKieSession().setGlobal("list", list); KogitoProcessInstance processInstance = kruntime.startProcess("RuleTask"); - kruntime.getKieSession().setGlobal("list", list); assertThat(list).hasSize(1); assertProcessInstanceFinished(processInstance, kruntime); } @@ -452,14 +451,16 @@ public void afterMatchFired(AfterMatchFiredEvent event) { params = new HashMap<>(); - processInstance = kruntime.startProcess("RuleTask", params); + KogitoProcessRuntime kruntime2 = createKogitoProcessRuntime("BPMN2-RuleTaskWithFact.bpmn2", "BPMN2-RuleTask3.drl"); + processInstance = kruntime2.startProcess("RuleTask", params); assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ERROR); + KogitoProcessRuntime kruntime3 = createKogitoProcessRuntime("BPMN2-RuleTaskWithFact.bpmn2", "BPMN2-RuleTask3.drl"); params = new HashMap<>(); params.put("x", "SomeString"); - processInstance = kruntime.startProcess("RuleTask", params); - assertProcessInstanceFinished(processInstance, kruntime); + processInstance = kruntime3.startProcess("RuleTask", params); + assertProcessInstanceFinished(processInstance, kruntime3); } @Test @@ -475,7 +476,6 @@ public void testRuleTaskAcrossSessions() throws Exception { KogitoProcessInstance processInstance2 = kruntime2.startProcess("RuleTask"); assertProcessInstanceFinished(processInstance1, kruntime); assertProcessInstanceFinished(processInstance2, kruntime2); - kruntime2.getKieSession().dispose(); // kruntime's session is disposed in the @AfterEach method } @Test From b20f0da3f75cc867ab6161330ddb1f14b5259e37 Mon Sep 17 00:00:00 2001 From: Martin Weiler Date: Wed, 25 Sep 2024 01:52:35 -0600 Subject: [PATCH 08/15] Ignore namespace differences during SVG comparison (#3680) --- .../main/java/org/kie/kogito/test/utils/CustomSVGDiffer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kogito-test-utils/src/main/java/org/kie/kogito/test/utils/CustomSVGDiffer.java b/kogito-test-utils/src/main/java/org/kie/kogito/test/utils/CustomSVGDiffer.java index 9fb5413f295..f1c46be2126 100644 --- a/kogito-test-utils/src/main/java/org/kie/kogito/test/utils/CustomSVGDiffer.java +++ b/kogito-test-utils/src/main/java/org/kie/kogito/test/utils/CustomSVGDiffer.java @@ -21,6 +21,7 @@ import org.xmlunit.builder.DiffBuilder; import org.xmlunit.builder.Input; import org.xmlunit.diff.ComparisonResult; +import org.xmlunit.diff.ComparisonType; import org.xmlunit.diff.Diff; import org.xmlunit.diff.DifferenceEvaluators; @@ -41,6 +42,9 @@ public CustomSVGDiffer(String content) { if (comparison.getControlDetails().getTarget().getNodeName().equals("svg")) { return ComparisonResult.SIMILAR; } + if (comparison.getType() == ComparisonType.NAMESPACE_URI) { + return ComparisonResult.SIMILAR; + } return outcome; })); } From d921c51b3ad87d00f30183d015c874067586af55 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti <65240126+fjtirado@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:08:25 +0200 Subject: [PATCH 09/15] [Fix #3677] Removing exception type from error message (#3679) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Fix #3677] Removing exception type from error message * Update jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java Co-authored-by: Gonzalo Muñoz * [Fix #3677] Alternative approach * [Fix #281] Adding specific exception handler --------- Co-authored-by: Gonzalo Muñoz --- .../exceptions/BaseExceptionsHandler.java | 6 +++-- .../process/runtime/MessageException.java | 27 +++++++++++++++++++ .../impl/WorkflowProcessInstanceImpl.java | 3 ++- .../actions/ErrorExpressionAction.java | 7 ++--- 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/MessageException.java diff --git a/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java b/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java index cdd3b2ad524..3da864ee7eb 100644 --- a/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java +++ b/addons/common/rest-exception-handler/src/main/java/org/kie/kogito/resource/exceptions/BaseExceptionsHandler.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.function.Function; +import org.kie.kogito.internal.process.runtime.MessageException; import org.kie.kogito.internal.process.workitem.InvalidLifeCyclePhaseException; import org.kie.kogito.internal.process.workitem.InvalidTransitionException; import org.kie.kogito.internal.process.workitem.NotAuthorizedException; @@ -66,6 +67,7 @@ public Function> getResponseGenerator() { } private final FunctionHolder defaultHolder = new FunctionHolder<>(ex -> ex, ex -> BaseExceptionsHandler.this::internalError); + private final FunctionHolder messageFunctionHolder = new FunctionHolder<>(ex -> Collections.singletonMap(MESSAGE, ex.getMessage()), ex -> BaseExceptionsHandler.this::badRequest); protected BaseExceptionsHandler() { mapper = new HashMap<>(); @@ -144,8 +146,8 @@ protected BaseExceptionsHandler() { mapper.put(WorkItemExecutionException.class, new FunctionHolder<>( ex -> Map.of(MESSAGE, ex.getMessage()), ex -> fromErrorCode(((WorkItemExecutionException) ex).getErrorCode()))); - - mapper.put(IllegalArgumentException.class, new FunctionHolder<>(ex -> Collections.singletonMap(MESSAGE, ex.getMessage()), ex -> BaseExceptionsHandler.this::badRequest)); + mapper.put(IllegalArgumentException.class, messageFunctionHolder); + mapper.put(MessageException.class, messageFunctionHolder); } private Function fromErrorCode(String errorCode) { diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/MessageException.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/MessageException.java new file mode 100644 index 00000000000..5aaccdc1cea --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/MessageException.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.internal.process.runtime; + +public class MessageException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public MessageException(String message) { + super(message); + } +} diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java index 79ef9e1d070..7ae6edf3fb1 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java @@ -85,6 +85,7 @@ import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer; import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess; +import org.kie.kogito.internal.process.runtime.MessageException; import org.kie.kogito.jobs.DurationExpirationTime; import org.kie.kogito.jobs.JobsService; import org.kie.kogito.jobs.ProcessInstanceJobDescription; @@ -1164,7 +1165,7 @@ public void setErrorState(NodeInstance nodeInstanceInError, Exception e) { this.nodeInstanceIdInError = nodeInstanceInError.getId(); this.errorCause = Optional.of(e); Throwable rootException = getRootException(e); - this.errorMessage = rootException.getClass().getCanonicalName() + " - " + rootException.getMessage(); + this.errorMessage = rootException instanceof MessageException ? rootException.getMessage() : rootException.getClass().getCanonicalName() + " - " + rootException.getMessage(); setState(STATE_ERROR); logger.error("Unexpected error while executing node {} in process instance {}", nodeInstanceInError.getNode().getName(), this.getStringId(), e); ((InternalProcessRuntime) getKnowledgeRuntime().getProcessRuntime()).getProcessEventSupport().fireOnError(this, nodeInstanceInError, getKnowledgeRuntime(), e); diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/actions/ErrorExpressionAction.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/actions/ErrorExpressionAction.java index a4b1f1da11d..04a22c1e2c1 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/actions/ErrorExpressionAction.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/actions/ErrorExpressionAction.java @@ -21,6 +21,7 @@ import org.jbpm.process.instance.ProcessInstance; import org.jbpm.workflow.instance.NodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessContext; +import org.kie.kogito.internal.process.runtime.MessageException; import com.fasterxml.jackson.databind.JsonNode; @@ -40,11 +41,11 @@ public void execute(KogitoProcessContext context) throws Exception { } } } else { - setError(context, expr.toString()); + setError(context, "The expression used for generating error message is not a valid one: " + expr.asString()); } } - private void setError(KogitoProcessContext context, String error) { - ((ProcessInstance) context.getProcessInstance()).setErrorState((NodeInstance) context.getNodeInstance(), new IllegalArgumentException(error)); + private void setError(KogitoProcessContext context, String message) { + ((ProcessInstance) context.getProcessInstance()).setErrorState((NodeInstance) context.getNodeInstance(), new MessageException(message)); } } From fff5c686d3ed0b3ebaaeec37896f1d0578fb0f23 Mon Sep 17 00:00:00 2001 From: Mario Fusco Date: Fri, 27 Sep 2024 09:24:10 +0200 Subject: [PATCH 10/15] [KIE-1492] Allow KieRuntimeBuilder to also create and provide StatelessKieSession (#3681) * [KIE-1492] Allow KieRuntimeBuilder to also create and provide StatelessKieSession * wip --- .../jbpm/process/instance/DummyKnowledgeRuntime.java | 6 ++++++ .../org/kie/kogito/codegen/AbstractCodegenIT.java | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java index ce4ef63213a..2f7da3c086c 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/DummyKnowledgeRuntime.java @@ -29,6 +29,7 @@ import org.drools.core.time.TimerService; import org.jbpm.workflow.instance.impl.CodegenNodeInstanceFactoryRegistry; import org.kie.api.KieBase; +import org.kie.api.command.Command; import org.kie.api.event.process.ProcessEventListener; import org.kie.api.event.process.ProcessEventManager; import org.kie.api.event.rule.AgendaEventListener; @@ -124,6 +125,11 @@ public KieRuntime getKieRuntime() { throw new UnsupportedOperationException(); } + @Override + public T execute(Command command) { + throw new UnsupportedOperationException(); + } + @Override public T getSessionClock() { return null; diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java index a09388af452..8758fed91dc 100644 --- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java +++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/AbstractCodegenIT.java @@ -94,6 +94,7 @@ protected enum TYPE { "import org.kie.api.KieBase;\n" + "import org.kie.api.builder.model.KieBaseModel;\n" + "import org.kie.api.runtime.KieSession;\n" + + "import org.kie.api.runtime.StatelessKieSession;\n" + "import org.drools.modelcompiler.KieBaseBuilder;\n" + "\n" + "\n" + @@ -120,6 +121,16 @@ protected enum TYPE { " public KieSession newKieSession(String sessionName) {\n" + " return null;\n" + " }\n" + + "\n" + + " @Override\n" + + " public StatelessKieSession newStatelessKieSession() {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @Override\n" + + " public StatelessKieSession newStatelessKieSession(String sessionName) {\n" + + " return null;\n" + + " }\n" + "}"; static { From 5e918c3a8d6bda96b6a1032de685d48662e97793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pere=20Fern=C3=A1ndez?= Date: Tue, 1 Oct 2024 08:57:02 +0200 Subject: [PATCH 11/15] incubator-kie-issues#1483: Create a common Kie Flyway initializer for Kie Modules (#3672) * incubator-kie-issues#1483: Create a common Kie Flyway initializer for Kie Modules * - cleanup * - cleanup * - ddls * - runtime configuration changes * - changing script locations * - Improved testing - README.md * - README.md - Api improvements * - minor changes --- addons/common/flyway/README.md | 151 +++++++++++++++ addons/common/flyway/pom.xml | 87 +++++++++ .../org/kie/flyway/KieFlywayException.java | 31 ++++ .../initializer/KieFlywayInitializer.java | 159 ++++++++++++++++ .../KieModuleFlywayConfigLoader.java | 29 +++ .../DefaultKieModuleFlywayConfigLoader.java | 110 +++++++++++ .../integration/KieFlywayConfiguration.java | 29 +++ .../integration/KieFlywayNamedModule.java | 25 +++ .../flyway/integration/KieFlywayRunner.java | 81 ++++++++ .../flyway/model/KieFlywayModuleConfig.java | 45 +++++ .../initializer/KieFlywayInitializerTest.java | 174 ++++++++++++++++++ ...efaultKieModuleFlywayConfigLoaderTest.java | 94 ++++++++++ .../integration/KieFlywayRunnerTest.java | 141 ++++++++++++++ .../TestKieFlywayConfiguration.java | 36 ++-- .../integration/TestKieFlywayNamedModule.java | 34 ++++ .../flyway/test/AbstractKieFlywayTest.java | 128 +++++++++++++ .../test/dataSources/H2TestDataSource.java | 62 +++++++ .../dataSources/PostgreSQLTestDataSource.java | 47 +++++ .../test/dataSources/TestDataSource.java | 33 ++++ .../org/kie/flyway/test/models/Customer.java | 23 +++ .../org/kie/flyway/test/models/Guitar.java | 23 +++ .../test/models/KieFlywayMigration.java | 23 +++ .../kie/flyway/test/models/TestModels.java | 50 +++++ .../flyway/test/utils/TestClassLoader.java | 47 +++++ .../resources/META-INF/kie-flyway.properties | 24 +++ .../kie-flyway.customers.properties | 24 +++ .../kie-flyway.customers2.properties | 24 +++ .../kie-flyway.duplicated1.properties | 24 +++ .../kie-flyway.duplicated2.properties | 24 +++ .../initializers/kie-flyway.empty.properties | 1 - .../kie-flyway.guitars.properties | 24 +++ .../kie-flyway.guitars_default.properties | 23 +++ .../kie-flyway.no.locations.properties | 20 ++ .../kie-flyway.wrong.format.properties | 22 +++ .../V1.0.5__Insert_game_characters_ansi.sql | 21 +++ .../h2/V1.0.5__Insert_game_characters_h2.sql | 21 +++ ...0.5__Insert_game_characters_postgresql.sql | 21 +++ .../ansi/V1.0.0__Create_table_ansi.sql | 26 +++ .../ansi/V1.0.1__Alter_table_ansi.sql | 20 ++ .../V1.0.2__Insert_book_characters_ansi.sql | 21 +++ .../customers/h2/V1.0.0__Create_table_h2.sql | 26 +++ .../customers/h2/V1.0.1__Alter_table_h2.sql | 20 ++ .../h2/V1.0.2__Insert_book_characters_h2.sql | 21 +++ .../V1.0.0__Create_table_postgresql.sql | 26 +++ .../V1.0.1__Alter_table_postgresql.sql | 20 ++ ...0.2__Insert_book_characters_postgresql.sql | 21 +++ .../V1.0.0__Create_guitars_table_ansi.sql | 26 +++ .../ansi/V1.0.1__Alter_guitars_table_ansi.sql | 20 ++ .../V1.0.2__Insert_fender_guitars_ansi.sql | 22 +++ .../V1.0.5__Insert_gibson_guitars_ansi.sql | 22 +++ .../h2/V1.0.0__Create_guitars_table_h2.sql | 26 +++ .../h2/V1.0.1__Alter_guitars_table_h2.sql | 20 ++ .../h2/V1.0.2__Insert_fender_guitars_h2.sql | 22 +++ .../h2/V1.0.5__Insert_gibson_guitars_h2.sql | 22 +++ ...1.0.0__Create_guitars_table_postgresql.sql | 26 +++ ...V1.0.1__Alter_guitars_table_postgresql.sql | 20 ++ ....0.2__Insert_fender_guitars_postgresql.sql | 22 +++ ....0.5__Insert_gibson_guitars_postgresql.sql | 22 +++ .../db/test/ansi/V1.0.0__Create_table.sql | 25 +++ .../db/test/ansi/V1.0.1__Alter_table.sql | 20 ++ .../db/test/ansi/V1.0.2__Insert_data.sql | 21 +++ .../db/test/h2/V1.0.0__Create_table.sql | 25 +++ .../db/test/h2/V1.0.1__Alter_table.sql | 20 ++ .../db/test/h2/V1.0.2__Insert_data.sql | 21 +++ .../test/postgresql/V1.0.0__Create_table.sql | 25 +++ .../test/postgresql/V1.0.1__Alter_table.sql | 20 ++ .../test/postgresql/V1.0.2__Insert_data.sql | 21 +++ .../ddl/src/assembly/db-scripts.xml | 11 +- .../src/assembly/productized-db-scripts.xml | 2 +- addons/common/persistence/jdbc/pom.xml | 5 +- .../resources/META-INF/kie-flyway.properties | 24 +++ .../ansi/V1.35.0__create_runtime_ansi.sql | 0 .../ansi/V10.0.0__add_business_key_ansi.sql | 0 .../ansi/V10.0.1__create_correlation_ansi.sql | 0 .../V1.35.0__create_runtime_PostgreSQL.sql | 0 .../V10.0.0__add_business_key_PostgreSQL.sql | 0 .../V10.0.1__alter_correlation_PostgreSQL.sql | 0 .../jdbc/AbstractProcessInstancesIT.java | 16 +- .../jdbc/PostgreSqlProcessInstancesIT.java | 2 +- .../correlation/JDBCCorrelationServiceIT.java | 20 +- .../common/persistence/postgresql/.gitignore | 2 +- addons/common/persistence/postgresql/pom.xml | 13 +- .../resources/META-INF/kie-flyway.properties | 23 +++ .../PostgresqlProcessInstancesIT.java | 16 +- addons/common/pom.xml | 1 + kogito-bom/pom.xml | 48 +++++ kogito-build/kogito-dependencies-bom/pom.xml | 13 ++ .../KogitoPostgreSqlContainer.java | 11 ++ quarkus/addons/flyway/deployment/pom.xml | 81 ++++++++ .../KieFlywayExtensionProcessor.java | 66 +++++++ quarkus/addons/flyway/pom.xml | 39 ++++ quarkus/addons/flyway/runtime/pom.xml | 93 ++++++++++ .../quarkus/KieFlywayQuarkusRecorder.java | 48 +++++ .../KieFlywayQuarkusRuntimeConfig.java | 71 +++++++ .../resources/META-INF/quarkus-extension.yaml | 36 ++++ .../src/main/resources/application.properties | 20 ++ .../persistence/jdbc/deployment/pom.xml | 6 +- .../addons/persistence/jdbc/runtime/pom.xml | 4 +- ...dOnPersistenceJDBCConfigSourceFactory.java | 83 --------- ...ersistenceJDBCConfigSourceFactoryTest.java | 85 --------- .../persistence/postgresql/deployment/pom.xml | 8 +- .../persistence/postgresql/runtime/pom.xml | 4 +- quarkus/addons/pom.xml | 1 + .../src/main/resources/application.properties | 3 +- .../src/main/resources/application.properties | 4 +- .../src/main/resources/application.properties | 4 +- springboot/addons/flyway/pom.xml | 73 ++++++++ .../KieFlywaySpringbootAutoConfiguration.java | 50 +++++ .../KieFlywaySpringbootInitializer.java | 51 +++++ .../KieFlywaySpringbootProperties.java | 63 +++++++ ...ieFlywaySpringbootInitializerDetector.java | 38 ++++ .../src/main/resources/META-INF/beans.xml | 0 .../main/resources/META-INF/spring.factories | 22 +++ ...ot.autoconfigure.AutoConfiguration.imports | 20 ++ springboot/addons/persistence/jdbc/pom.xml | 4 + .../addons/persistence/postgresql/pom.xml | 4 + springboot/addons/pom.xml | 1 + .../src/main/resources/application.properties | 5 +- .../src/main/resources/application.properties | 2 + .../PostgreSqlSpringBootTestResource.java | 6 - 120 files changed, 3543 insertions(+), 263 deletions(-) create mode 100644 addons/common/flyway/README.md create mode 100644 addons/common/flyway/pom.xml create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/KieFlywayException.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieModuleFlywayConfigLoader.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoader.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayConfiguration.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayNamedModule.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayRunner.java create mode 100644 addons/common/flyway/src/main/java/org/kie/flyway/model/KieFlywayModuleConfig.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/initializer/KieFlywayInitializerTest.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoaderTest.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/integration/KieFlywayRunnerTest.java rename quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSource.java => addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayConfiguration.java (52%) create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayNamedModule.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/AbstractKieFlywayTest.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/H2TestDataSource.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/TestDataSource.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/models/Customer.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/models/Guitar.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/models/KieFlywayMigration.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/models/TestModels.java create mode 100644 addons/common/flyway/src/test/java/org/kie/flyway/test/utils/TestClassLoader.java create mode 100644 addons/common/flyway/src/test/resources/META-INF/kie-flyway.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.customers.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.customers2.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated1.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated2.properties rename quarkus/addons/persistence/jdbc/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory => addons/common/flyway/src/test/resources/initializers/kie-flyway.empty.properties (90%) create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars_default.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.no.locations.properties create mode 100644 addons/common/flyway/src/test/resources/initializers/kie-flyway.wrong.format.properties create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/ansi/V1.0.5__Insert_game_characters_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/h2/V1.0.5__Insert_game_characters_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/postgresql/V1.0.5__Insert_game_characters_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.0__Create_table_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.1__Alter_table_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.2__Insert_book_characters_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.0__Create_table_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.1__Alter_table_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.2__Insert_book_characters_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.0__Create_table_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.1__Alter_table_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.2__Insert_book_characters_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.0__Create_guitars_table_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.1__Alter_guitars_table_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.2__Insert_fender_guitars_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.5__Insert_gibson_guitars_ansi.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.0__Create_guitars_table_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.1__Alter_guitars_table_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.2__Insert_fender_guitars_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.5__Insert_gibson_guitars_h2.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.0__Create_guitars_table_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.1__Alter_guitars_table_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.2__Insert_fender_guitars_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.5__Insert_gibson_guitars_postgresql.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.0__Create_table.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.1__Alter_table.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.2__Insert_data.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.0__Create_table.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.1__Alter_table.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.2__Insert_data.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.0__Create_table.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.1__Alter_table.sql create mode 100644 addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.2__Insert_data.sql create mode 100644 addons/common/persistence/jdbc/src/main/resources/META-INF/kie-flyway.properties rename addons/common/persistence/jdbc/src/main/resources/{db => kie-flyway/db/persistence-jdbc}/ansi/V1.35.0__create_runtime_ansi.sql (100%) rename addons/common/persistence/jdbc/src/main/resources/{db => kie-flyway/db/persistence-jdbc}/ansi/V10.0.0__add_business_key_ansi.sql (100%) rename addons/common/persistence/jdbc/src/main/resources/{db => kie-flyway/db/persistence-jdbc}/ansi/V10.0.1__create_correlation_ansi.sql (100%) rename addons/common/persistence/jdbc/src/main/resources/{db => kie-flyway/db/persistence-jdbc}/postgresql/V1.35.0__create_runtime_PostgreSQL.sql (100%) rename addons/common/persistence/jdbc/src/main/resources/{db => kie-flyway/db/persistence-jdbc}/postgresql/V10.0.0__add_business_key_PostgreSQL.sql (100%) rename addons/common/persistence/jdbc/src/main/resources/{db => kie-flyway/db/persistence-jdbc}/postgresql/V10.0.1__alter_correlation_PostgreSQL.sql (100%) create mode 100644 addons/common/persistence/postgresql/src/main/resources/META-INF/kie-flyway.properties create mode 100644 quarkus/addons/flyway/deployment/pom.xml create mode 100644 quarkus/addons/flyway/deployment/src/main/java/org/kie/flyway/quarkus/deployment/KieFlywayExtensionProcessor.java create mode 100644 quarkus/addons/flyway/pom.xml create mode 100644 quarkus/addons/flyway/runtime/pom.xml create mode 100644 quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRecorder.java create mode 100644 quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRuntimeConfig.java create mode 100644 quarkus/addons/flyway/runtime/src/main/resources/META-INF/quarkus-extension.yaml create mode 100644 quarkus/addons/flyway/runtime/src/main/resources/application.properties delete mode 100644 quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactory.java delete mode 100644 quarkus/addons/persistence/jdbc/runtime/src/test/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactoryTest.java create mode 100644 springboot/addons/flyway/pom.xml create mode 100644 springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootAutoConfiguration.java create mode 100644 springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootInitializer.java create mode 100644 springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootProperties.java create mode 100644 springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/detector/KieFlywaySpringbootInitializerDetector.java create mode 100644 springboot/addons/flyway/src/main/resources/META-INF/beans.xml create mode 100644 springboot/addons/flyway/src/main/resources/META-INF/spring.factories create mode 100644 springboot/addons/flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/addons/common/flyway/README.md b/addons/common/flyway/README.md new file mode 100644 index 00000000000..5efde7bf4f3 --- /dev/null +++ b/addons/common/flyway/README.md @@ -0,0 +1,151 @@ + + +# KIE Flyway Add-On + +## Goal + +This add-on is a utility intended to help bootstrapping the application Data Base when running in a `compact` setup, +when more than one`extension` or `add-on` that require persistence co-exist in the same application. + +This add-on will be using a managed Flyway to initialize and upgrade each `extension`/`add-on` DB +instead of using the Platform (Quarkus/Springboot) specific Flyway integration, by this we achieve: +* Simple setups in the `application.properties`. No need to configure Flyway unless the customer requires for its + own needs. +* Component-Based DB Management: the DB management (via Flyway `migrations`) will be executed independently by component + (not globally), keeping a separate index for each component to avoid collisions and conflict between different component versions. +* Multi DB Support: a single module can provide SQL scripts for different DB vendors (and default as a fallback) that + will be loaded depending on the application configuration + +> *IMPORTANT*: The usage of this add-on should be reserved only for development/test/examples purposes, and it is not recommended +> using it in productive environments. + + + +## KIE Flyway Module Configuration + +In order to allow the *KIE Flyway Initializer* identify the DB needs of a specific component (`extensions` or `add-on`) +the component has to meet the following requirements: + +* Provide a `kie-flyway.properties` descriptor file in `/src/main/resources/META-INF/kie-flyway.properties`. The file + should provide the following information: + * `module.name`: logic name that identifies the module. This identifier will be used during the Data Base initialization process + to generate the index table (`kie_flyway_history_`) that will keep track of the modules table changes. + If there are multiple implementations of the same module (ej: `kie-addons-persistence-jdbc` / `kie-addons-persistence-postgresql`) + they should use the same name. + * `module.locations.`: map containing the module `.sql` scripts location paths organized by database type (`postgresql`, `h2`...) to initialize the DB + (ej: `module.locations.postgresql=classpath:kie-flyway/db/test-module/postgresql`), the locations can be a comma-separated list to use multiple `.sql` locations in a single migration. + It's also possible using a `default` locations (`module.locations.default=...`) as a fallback to provide a default initialization + if no vendor-specific isn't available. It is important to avoid using the default flyway location (`src/main/resourcs/db/migrations`) to avoid + collisions with the Platform Flyway integration. + +Example of `kie-flyway.properties` file: +```properties +# Name that identifies the module +module.name=runtime-persistence + +# Script locations for the current module +module.locations.h2=classpath:kie-flyway/db/persistence-jdbc/h2 +module.locations.postgresql=classpath:kie-flyway/db/persistence-jdbc/postgresql +# Default sql locations if the application db type isn't none of the above (ej: oracle) +module.locations.default=classpath:kie-flyway/db/persistence-jdbc/ansi +``` + +* SQL Migration files: the needed SQL files to initialize the module DB. They should be stored in a unique path for the + component inside `src/main/resources` (ej: `src/main/resources/kie-flyway/db/`), and grouped by database type. + +Example of folder structure: + +``` +kie-persistence-jdbc +└─── src/main/resources + └─── META-INF + │ └─── kie-flyway.properties + └─── kie-flyway/db/persistence-jdbc + └─── ansi + │ V1.35.0__create_runtime_ansi.sql + │ V10.0.0__add_business_key_ansi.sql + │ V10.0.1__create_correlation_ansi.sql + └─── postgresql + V1.35.0__create_runtime_PostgreSQL.sql + V10.0.0__add_business_key_PostgreSQL.sql + V10.0.1__create_correlation_PostgreSQL.sql +``` + +## Application configurations + +### Enabling Kie Flyway Migration +KIE Flyway is disabled by default (in Quarkus is enabled in `test`/`dev` profiles) and can be enabled / disabled with +`kie.flyway.enabled` property in the `application.properties` (by default is false) + +### Excluding specific KIE Modules via configuration. +In some cases you may want to exclude the KIE Modules present in your application from the KIE Flyway initialization, to do so you can use +`kie.flyway.modules..enabled` property in the `application.properties` + +Example of `application.properties` +```properties +... + +# KIE Flyway setup +kie.flyway.enabled=true +kie.flyway.modules."data-index".enabled=false +kie.flyway.modules."jobs-service".enabled=false +``` + +## Usage +KIE Flyway exposes the `KieFlywayInitializer` as entry point of the add-on and exposes a Fluent Api to configure it +and run it. This component will be in charge of loading all the `kie-flyway.properties` available in the application and run +migrations for each of them. + +The required information that must be provided to the initializer is: +* DataSource (`java.sql.DataSource`) where the initialization should be executed. It should be the default application Data Source + +```java +import org.kie.flyway.initializer.KieFlywayInitializer; + +... + KieFlywayInitializer.builder() + .withDatasource(dataSource) + .build() + .migrate(); +``` + +Additional Parameters that can be used: +* Custom ClassLoader to load the `kie-flyway.properties` from. +* Module Exclusions (`Collection`) t + +```java +import org.kie.flyway.initializer.KieFlywayInitializer; + +... + KieFlywayInitializer.builder() + .withDatasource(dataSource) + .withClassLoader(this.getClass().getClassLoader()) + .withModuleExclusions(List.of("data-index", "jobs-service")) + .build() + .migrate(); +``` + +> NOTE: The platform-specific add-ons (Quarkus/Spring-Boot) will be in charge to obtain the DataSource and DataBase type +> and correctly configure the `KieFlywayInitializer` according to the `application.properties` and use it on during the application startup. + + + + + diff --git a/addons/common/flyway/pom.xml b/addons/common/flyway/pom.xml new file mode 100644 index 00000000000..6a79414f19a --- /dev/null +++ b/addons/common/flyway/pom.xml @@ -0,0 +1,87 @@ + + + + + kogito-addons-common-parent + org.kie + 999-SNAPSHOT + + 4.0.0 + + kie-addons-flyway + KIE :: Add-Ons :: Flyway + + + org.kie.flyway + + + + + org.flywaydb + flyway-core + + + + org.slf4j + slf4j-api + + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.mockito + mockito-core + test + + + org.assertj + assertj-core + test + + + org.postgresql + postgresql + test + + + org.kie.kogito + kogito-test-utils + test + + + com.h2database + h2 + test + + + + \ No newline at end of file diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/KieFlywayException.java b/addons/common/flyway/src/main/java/org/kie/flyway/KieFlywayException.java new file mode 100644 index 00000000000..becf0325f12 --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/KieFlywayException.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway; + +public class KieFlywayException extends RuntimeException { + + public KieFlywayException(String message) { + super(message); + } + + public KieFlywayException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java new file mode 100644 index 00000000000..8986b7a428f --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.initializer; + +import java.sql.Connection; +import java.util.*; +import java.util.stream.Collectors; + +import javax.sql.DataSource; + +import org.flywaydb.core.Flyway; +import org.kie.flyway.KieFlywayException; +import org.kie.flyway.initializer.impl.DefaultKieModuleFlywayConfigLoader; +import org.kie.flyway.model.KieFlywayModuleConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.util.stream.Collectors.groupingBy; + +public class KieFlywayInitializer { + private static final String KIE_FLYWAY_BASELINE_VERSION = "0.0"; + + private static final String KIE_FLYWAY_BASELINE_MESSAGE_TEMPLATE = "Kie Flyway Baseline - %s"; + + private static final String KIE_FLYWAY_INDEX_TABLE_INDEX_TEMPLATE = "kie_flyway_history_%s"; + + private static final Logger LOGGER = LoggerFactory.getLogger(KieFlywayInitializer.class); + + private final KieModuleFlywayConfigLoader configLoader; + private final DataSource dataSource; + private final String databaseType; + private final List moduleExclusions; + + private KieFlywayInitializer(KieModuleFlywayConfigLoader configLoader, DataSource dataSource, Collection moduleExclusions) { + this.configLoader = configLoader; + this.dataSource = dataSource; + this.databaseType = getDataSourceType(dataSource); + this.moduleExclusions = new ArrayList<>(moduleExclusions); + } + + public void migrate() { + LOGGER.debug("Starting Kie Flyway migration."); + Collection configs = configLoader.loadModuleConfigs(); + + checkDuplicatedModuleConfigs(configs); + + LOGGER.debug("Found {} configured Kie Flyway modules.", configs.size()); + + configs.forEach(this::runFlyway); + } + + private void checkDuplicatedModuleConfigs(Collection configs) { + List duplicatedModules = configs.stream() + .collect(groupingBy(kieFlywayModuleConfig -> kieFlywayModuleConfig.getModule().toLowerCase(), Collectors.counting())) + .entrySet() + .stream().filter(entry -> entry.getValue() > 1) + .map(Map.Entry::getKey) + .toList(); + + if (!duplicatedModules.isEmpty()) { + LOGGER.warn("Cannot run Kie Flyway migration: Duplicated modules found `{}`", String.join(", ", duplicatedModules)); + throw new KieFlywayException("Cannot run Kie Flyway migration: Duplicated Modules found " + String.join(", ", duplicatedModules)); + } + } + + private String getDataSourceType(DataSource dataSource) { + try (Connection con = dataSource.getConnection()) { + return con.getMetaData().getDatabaseProductName().toLowerCase(); + } catch (Exception e) { + LOGGER.error("Kie Flyway: Couldn't extract database product name from datasource ", e); + throw new KieFlywayException("Kie Flyway: Couldn't extract database product name from datasource.", e); + } + } + + private void runFlyway(KieFlywayModuleConfig config) { + LOGGER.debug("Running Flyway for module: {}", config.getModule()); + + if (moduleExclusions.contains(config.getModule())) { + LOGGER.debug("Skipping module: {}", config.getModule()); + return; + } + + String[] locations = config.getDBScriptLocations(databaseType); + + if (Objects.isNull(locations)) { + LOGGER.warn("Cannot run Flyway migration for module `{}`, cannot find SQL Script locations for db `{}`", config.getModule(), databaseType); + throw new KieFlywayException("Cannot run Flyway migration for module `" + config.getModule() + "`, cannot find SQL Script locations for db `" + databaseType + "`"); + } + + Flyway.configure() + .table(KIE_FLYWAY_INDEX_TABLE_INDEX_TEMPLATE.formatted(config.getModule().replaceAll("[^A-Za-z0-9]", "_")).toLowerCase()) + .dataSource(dataSource) + .createSchemas(true) + .baselineOnMigrate(true) + .baselineVersion(KIE_FLYWAY_BASELINE_VERSION) + .baselineDescription(KIE_FLYWAY_BASELINE_MESSAGE_TEMPLATE.formatted(config.getModule())) + .locations(locations) + .load() + .migrate(); + + LOGGER.debug("Flyway migration complete."); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private KieModuleFlywayConfigLoader configLoader; + private DataSource dataSource; + private final List moduleExclusions = new ArrayList<>(); + + public Builder withClassLoader(ClassLoader classLoader) { + this.configLoader = new DefaultKieModuleFlywayConfigLoader(classLoader); + return this; + } + + public Builder withDatasource(DataSource dataSource) { + this.dataSource = dataSource; + return this; + } + + public Builder withModuleExclusions(Collection moduleExclusions) { + this.moduleExclusions.addAll(moduleExclusions); + return this; + } + + public KieFlywayInitializer build() { + if (Objects.isNull(dataSource)) { + throw new KieFlywayException("Cannot create KieFlywayInitializer migration, dataSource is null."); + } + + if (Objects.isNull(configLoader)) { + LOGGER.warn("ModuleConfigLoader not configured, falling back to default."); + this.configLoader = new DefaultKieModuleFlywayConfigLoader(); + } + + return new KieFlywayInitializer(configLoader, dataSource, moduleExclusions); + } + } + +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieModuleFlywayConfigLoader.java b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieModuleFlywayConfigLoader.java new file mode 100644 index 00000000000..cc3f15b914e --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieModuleFlywayConfigLoader.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.initializer; + +import java.util.Collection; + +import org.kie.flyway.model.KieFlywayModuleConfig; + +public interface KieModuleFlywayConfigLoader { + + Collection loadModuleConfigs(); +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoader.java b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoader.java new file mode 100644 index 00000000000..71665bc63d8 --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoader.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.initializer.impl; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.stream.Collectors; + +import org.kie.flyway.KieFlywayException; +import org.kie.flyway.initializer.KieModuleFlywayConfigLoader; +import org.kie.flyway.model.KieFlywayModuleConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DefaultKieModuleFlywayConfigLoader implements KieModuleFlywayConfigLoader { + + public static String KIE_FLYWAY_DESCRIPTOR_FILE_NAME = "kie-flyway.properties"; + + public static String KIE_FLYWAY_DESCRIPTOR_FILE_LOCATION = "META-INF" + File.separator + KIE_FLYWAY_DESCRIPTOR_FILE_NAME; + + public static final String MODULE_PREFIX = "module."; + public static final String MODULE_NAME_KEY = MODULE_PREFIX + "name"; + public static final String MODULE_LOCATIONS_KEY = MODULE_PREFIX + "locations"; + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultKieModuleFlywayConfigLoader.class); + + private final ClassLoader classLoader; + + public DefaultKieModuleFlywayConfigLoader() { + this(Thread.currentThread().getContextClassLoader()); + } + + public DefaultKieModuleFlywayConfigLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public Collection loadModuleConfigs() { + return Optional.ofNullable(this.classLoader).orElse(this.getClass().getClassLoader()) + .resources(KIE_FLYWAY_DESCRIPTOR_FILE_LOCATION) + .map(this::toModuleFlywayConfig) + .toList(); + } + + private KieFlywayModuleConfig toModuleFlywayConfig(URL resourceUrl) { + LOGGER.debug("Loading configuration from {}", resourceUrl); + + try (InputStream inputStream = resourceUrl.openStream()) { + Properties properties = new Properties(); + properties.load(inputStream); + + String moduleName = properties.getProperty(MODULE_NAME_KEY); + + if (Objects.isNull(moduleName)) { + LOGGER.warn("Could not load module name from file `{}`", resourceUrl); + throw new KieFlywayException("Could not load module name from `" + resourceUrl + "`"); + } + + LOGGER.debug("Loading Kie Flyway Module {}", moduleName); + + Map locations = properties.keySet() + .stream() + .map(String::valueOf) + .filter(moduleProperty -> moduleProperty.startsWith(MODULE_LOCATIONS_KEY)) + .map(dbLocationsProperty -> { + LOGGER.debug("Loading location: {}", dbLocationsProperty); + // Splitting the key (`module.locations.`) to obtain the dbType + String[] dbLocationsPropertyArray = dbLocationsProperty.split("\\."); + if (dbLocationsPropertyArray.length != 3) { + throw new KieFlywayException("Cannot load module `" + moduleName + "` config, file has wrong format"); + } + String[] locationsArray = properties.getProperty(dbLocationsProperty).split(","); + + return Map.entry(dbLocationsPropertyArray[2], locationsArray); + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (locations.isEmpty()) { + LOGGER.warn("Kie Flyway module `{}` has no locations ", moduleName); + } + + KieFlywayModuleConfig module = new KieFlywayModuleConfig(moduleName, locations); + + LOGGER.debug("Successfully loaded configuration for module {}", module.getModule()); + + return module; + } catch (Exception e) { + LOGGER.warn("Could not load configuration from {}", resourceUrl, e); + throw new KieFlywayException("Could not load ModuleFlywayConfig", e); + } + } +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayConfiguration.java b/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayConfiguration.java new file mode 100644 index 00000000000..c99dba53b8b --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayConfiguration.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.integration; + +import java.util.Map; + +public interface KieFlywayConfiguration { + + boolean isEnabled(); + + Map getModules(); +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayNamedModule.java b/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayNamedModule.java new file mode 100644 index 00000000000..e3ebe1b6a06 --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayNamedModule.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.integration; + +public interface KieFlywayNamedModule { + + boolean isEnabled(); +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayRunner.java b/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayRunner.java new file mode 100644 index 00000000000..47d55a96e6b --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/integration/KieFlywayRunner.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.integration; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +import javax.sql.DataSource; + +import org.kie.flyway.KieFlywayException; +import org.kie.flyway.initializer.KieFlywayInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KieFlywayRunner { + private static final Logger LOGGER = LoggerFactory.getLogger(KieFlywayRunner.class); + + private final ClassLoader classLoader; + private final KieFlywayConfiguration configuration; + + private KieFlywayRunner(KieFlywayConfiguration configuration) { + this(configuration, Thread.currentThread().getContextClassLoader()); + } + + protected KieFlywayRunner(KieFlywayConfiguration configuration, ClassLoader classLoader) { + this.configuration = configuration; + this.classLoader = classLoader; + } + + public static KieFlywayRunner get(KieFlywayConfiguration configuration) { + return new KieFlywayRunner(configuration); + } + + public void runFlyway(DataSource dataSource) { + assertValue(configuration, "Kie Flyway: Cannot run Kie Flyway migration configuration is null."); + + if (!configuration.isEnabled()) { + LOGGER.warn("Kie Flyway is disabled, skipping initialization."); + return; + } + + assertValue(dataSource, "Kie Flyway: Cannot run Kie Flyway migration default datasource is null"); + + Collection excludedModules = configuration.getModules() + .entrySet() + .stream().filter(entry -> !entry.getValue().isEnabled()) + .map(Map.Entry::getKey) + .toList(); + + KieFlywayInitializer.builder() + .withDatasource(dataSource) + .withClassLoader(classLoader) + .withModuleExclusions(excludedModules) + .build().migrate(); + } + + private void assertValue(Object value, String message) { + if (Objects.isNull(value)) { + LOGGER.warn(message); + throw new KieFlywayException(message); + } + } +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/model/KieFlywayModuleConfig.java b/addons/common/flyway/src/main/java/org/kie/flyway/model/KieFlywayModuleConfig.java new file mode 100644 index 00000000000..16321a618e9 --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/model/KieFlywayModuleConfig.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.model; + +import java.util.Map; +import java.util.TreeMap; + +public class KieFlywayModuleConfig { + + public static final String DEFAULT_DB = "default"; + + private final String module; + private final Map locations = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + + public KieFlywayModuleConfig(String module, Map locations) { + this.module = module; + this.locations.putAll(locations); + } + + public String getModule() { + return module; + } + + public String[] getDBScriptLocations(String dbType) { + return this.locations.getOrDefault(dbType, locations.get(DEFAULT_DB)); + } + +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/initializer/KieFlywayInitializerTest.java b/addons/common/flyway/src/test/java/org/kie/flyway/initializer/KieFlywayInitializerTest.java new file mode 100644 index 00000000000..425c3b32c9b --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/initializer/KieFlywayInitializerTest.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.initializer; + +import java.util.*; +import java.util.stream.Stream; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.kie.flyway.KieFlywayException; +import org.kie.flyway.test.AbstractKieFlywayTest; +import org.kie.flyway.test.dataSources.H2TestDataSource; +import org.kie.flyway.test.dataSources.PostgreSQLTestDataSource; +import org.kie.flyway.test.dataSources.TestDataSource; +import org.kie.flyway.test.utils.TestClassLoader; +import org.kie.kogito.testcontainers.KogitoPostgreSqlContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import static org.kie.flyway.test.models.TestModels.*; + +@Testcontainers +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class KieFlywayInitializerTest extends AbstractKieFlywayTest { + + @Container + private static final KogitoPostgreSqlContainer PG_CONTAINER = new KogitoPostgreSqlContainer(); + + private static PostgreSQLTestDataSource PG_DATA_SOURCE; + private static H2TestDataSource H2_DATA_SOURCE; + + private TestClassLoader classLoader; + + @BeforeAll + public static void start() { + PG_CONTAINER.start(); + PG_DATA_SOURCE = new PostgreSQLTestDataSource(PG_CONTAINER); + H2_DATA_SOURCE = new H2TestDataSource(); + } + + public static Stream getDataSources() { + return Stream.of(Arguments.of(PG_DATA_SOURCE), + Arguments.of(H2_DATA_SOURCE)); + } + + @BeforeEach + public void init() { + classLoader = new TestClassLoader(this.getClass().getClassLoader()); + } + + @ParameterizedTest + @MethodSource("getDataSources") + public void testTestKieFlywayInitializerBuilderValidations(TestDataSource dataSource) { + Assertions.assertThatThrownBy(() -> KieFlywayInitializer.builder() + .build()).isInstanceOf(KieFlywayException.class) + .hasMessage("Cannot create KieFlywayInitializer migration, dataSource is null."); + + classLoader.addKieFlywayModule("initializers/kie-flyway.no.locations.properties"); + + Assertions.assertThatThrownBy(() -> KieFlywayInitializer.builder() + .withDatasource(dataSource.getDataSource()) + .withClassLoader(classLoader).build().migrate()) + .isInstanceOf(KieFlywayException.class) + .hasMessageContaining("Cannot run Flyway migration for module `no-locations`, cannot find SQL Script locations for db"); + } + + @ParameterizedTest + @MethodSource("getDataSources") + public void testKieFlywayInitializerValidations(TestDataSource dataSource) { + classLoader.addKieFlywayModule("initializers/kie-flyway.duplicated1.properties"); + classLoader.addKieFlywayModule("initializers/kie-flyway.duplicated1.properties"); + classLoader.addKieFlywayModule("initializers/kie-flyway.duplicated2.properties"); + classLoader.addKieFlywayModule("initializers/kie-flyway.duplicated2.properties"); + + Assertions.assertThatThrownBy(() -> { + KieFlywayInitializer.builder() + .withDatasource(dataSource.getDataSource()) + .withClassLoader(classLoader) + .build() + .migrate(); + }).isInstanceOf(KieFlywayException.class) + .hasMessage("Cannot run Kie Flyway migration: Duplicated Modules found test-duplicated-1, test-duplicated-2"); + + } + + @Order(1) + @ParameterizedTest + @MethodSource("getDataSources") + public void testFlywayMigrationsWithExclusions(TestDataSource dataSource) { + + classLoader.addKieFlywayModule("initializers/kie-flyway.customers.properties"); + classLoader.addKieFlywayModule("initializers/kie-flyway.guitars.properties"); + + KieFlywayInitializer.builder() + .withDatasource(dataSource.getDataSource()) + .withClassLoader(classLoader) + .withModuleExclusions(List.of("guitars")) + .build() + .migrate(); + + validateKieFlywayIndex("customers", EXPECTED_CUSTOMERS_MIGRATIONS.stream().limit(3).toList(), dataSource); + validateCustomersData(EXPECTED_CUSTOMERS.stream().limit(2).toList(), dataSource); + + // Guitars module has been excluded, so it shouldn't be installed. Verifying that tables don't exist + verifyTableDoesntExist("guitars", dataSource); + verifyTableDoesntExist("kie_flyway_history_guitars", dataSource); + } + + @Order(2) + @ParameterizedTest + @MethodSource("getDataSources") + public void testFlywayMigrationsUpgrade(TestDataSource dataSource) { + + classLoader.addKieFlywayModule("initializers/kie-flyway.customers2.properties"); + classLoader.addKieFlywayModule("initializers/kie-flyway.guitars.properties"); + + KieFlywayInitializer.builder() + .withDatasource(dataSource.getDataSource()) + .withClassLoader(classLoader) + .withModuleExclusions(List.of("test-3")) + .build() + .migrate(); + + validateKieFlywayIndex("customers", EXPECTED_CUSTOMERS_MIGRATIONS, dataSource); + validateCustomersData(EXPECTED_CUSTOMERS, dataSource); + + validateKieFlywayIndex("guitars", EXPECTED_GUITARS_MIGRATIONS, dataSource); + validateGuitarsData(dataSource); + } + + @Test + public void testFlywayMigrationWithFallbackDBType() { + classLoader.addKieFlywayModule("initializers/kie-flyway.guitars_default.properties"); + + H2TestDataSource dataSource = new H2TestDataSource(); + + KieFlywayInitializer.builder() + .withDatasource(dataSource.getDataSource()) + .withClassLoader(classLoader) + .build() + .migrate(); + + validateKieFlywayIndex("guitars", EXPECTED_GUITARS_MIGRATIONS, dataSource); + validateGuitarsData(dataSource); + + dataSource.shutDown(); + } + + @AfterAll + public static void shutdown() { + H2_DATA_SOURCE.shutDown(); + } + +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoaderTest.java b/addons/common/flyway/src/test/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoaderTest.java new file mode 100644 index 00000000000..139f48c649c --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/initializer/impl/DefaultKieModuleFlywayConfigLoaderTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.initializer.impl; + +import java.util.Collection; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.kie.flyway.KieFlywayException; +import org.kie.flyway.model.KieFlywayModuleConfig; +import org.kie.flyway.test.utils.TestClassLoader; + +public class DefaultKieModuleFlywayConfigLoaderTest { + + private static final String H2_LOCATIONS = "classpath:kie-flyway/db/test/h2"; + private static final String PGSQL_LOCATIONS = "classpath:kie-flyway/db/test/postgresql"; + private static final String DEFAULT_LOCATIONS = "classpath:kie-flyway/db/test/ansi"; + + private TestClassLoader testClassLoader; + private DefaultKieModuleFlywayConfigLoader flywayConfigLoader; + + @BeforeEach + public void init() { + this.testClassLoader = new TestClassLoader(this.getClass().getClassLoader()); + this.flywayConfigLoader = new DefaultKieModuleFlywayConfigLoader(testClassLoader); + } + + @Test + public void testDefaultLoading() { + + Collection configs = flywayConfigLoader.loadModuleConfigs(); + + Assertions.assertThat(configs) + .hasSize(1); + + Assertions.assertThat(configs.iterator().next()) + .isNotNull() + .hasFieldOrPropertyWithValue("module", "test") + .returns(H2_LOCATIONS, kieFlywayModuleConfig -> kieFlywayModuleConfig.getDBScriptLocations("h2")[0]) + .returns(PGSQL_LOCATIONS, kieFlywayModuleConfig -> kieFlywayModuleConfig.getDBScriptLocations("postgresql")[0]) + .returns(DEFAULT_LOCATIONS, kieFlywayModuleConfig -> kieFlywayModuleConfig.getDBScriptLocations("db2")[0]); + } + + @Test + public void testEmptyConfigFile() { + testClassLoader.addKieFlywayModule("initializers/kie-flyway.empty.properties"); + + Assertions.assertThatThrownBy(() -> flywayConfigLoader.loadModuleConfigs()) + .isInstanceOf(KieFlywayException.class) + .hasMessage("Could not load ModuleFlywayConfig") + .cause() + .isInstanceOf(KieFlywayException.class) + .hasMessageStartingWith("Could not load module name from"); + } + + @Test + public void testWrongLocationsFormat() { + testClassLoader.addKieFlywayModule("initializers/kie-flyway.wrong.format.properties"); + + Assertions.assertThatThrownBy(() -> flywayConfigLoader.loadModuleConfigs()) + .isInstanceOf(KieFlywayException.class) + .hasMessage("Could not load ModuleFlywayConfig") + .cause() + .isInstanceOf(KieFlywayException.class) + .hasMessage("Cannot load module `test-wrong-format` config, file has wrong format"); + } + + @Test + public void testWrongResourceFile() { + testClassLoader.addKieFlywayModule("wrong content"); + + Assertions.assertThatThrownBy(() -> flywayConfigLoader.loadModuleConfigs()) + .isInstanceOf(KieFlywayException.class) + .hasMessage("Could not load ModuleFlywayConfig"); + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/integration/KieFlywayRunnerTest.java b/addons/common/flyway/src/test/java/org/kie/flyway/integration/KieFlywayRunnerTest.java new file mode 100644 index 00000000000..bd510d9994f --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/integration/KieFlywayRunnerTest.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.integration; + +import java.util.HashMap; + +import javax.sql.DataSource; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.*; +import org.kie.flyway.KieFlywayException; +import org.kie.flyway.test.AbstractKieFlywayTest; +import org.kie.flyway.test.dataSources.H2TestDataSource; +import org.kie.flyway.test.dataSources.TestDataSource; +import org.kie.flyway.test.utils.TestClassLoader; + +import static org.kie.flyway.test.models.TestModels.*; +import static org.mockito.Mockito.mock; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class KieFlywayRunnerTest extends AbstractKieFlywayTest { + + private static final TestDataSource TEST_DATA_SOURCE; + + static { + TEST_DATA_SOURCE = new H2TestDataSource(); + } + + private TestClassLoader testClassLoader; + private TestKieFlywayConfiguration testConfiguration; + + @BeforeEach + public void init() { + testClassLoader = new TestClassLoader(this.getClass().getClassLoader()); + testConfiguration = new TestKieFlywayConfiguration(true, new HashMap<>()); + } + + @Test + public void testValidations() { + Assertions.assertThatThrownBy(() -> KieFlywayRunner.get(null).runFlyway(null)) + .isInstanceOf(KieFlywayException.class) + .hasMessage("Kie Flyway: Cannot run Kie Flyway migration configuration is null."); + + Assertions.assertThatThrownBy(() -> KieFlywayRunner.get(testConfiguration).runFlyway(null)).isInstanceOf(KieFlywayException.class) + .hasMessage("Kie Flyway: Cannot run Kie Flyway migration default datasource is null"); + + // Mocking DataSource to make sure we cannot resolve dbType. + DataSource mockedDS = mock(DataSource.class); + + Assertions.assertThatThrownBy(() -> KieFlywayRunner.get(testConfiguration).runFlyway(mockedDS)) + .isInstanceOf(KieFlywayException.class) + .hasMessage("Kie Flyway: Couldn't extract database product name from datasource."); + } + + @Test + @Order(0) + public void testFlywayMigrationsWithDisabledConfig() { + testClassLoader.addKieFlywayModule("initializers/kie-flyway.customers.properties"); + testClassLoader.addKieFlywayModule("initializers/kie-flyway.guitars.properties"); + + testConfiguration.setEnabled(false); + + TestKieFlywayRunner.get(testConfiguration, testClassLoader) + .runFlyway(TEST_DATA_SOURCE.getDataSource()); + + verifyTableDoesntExist("customers", TEST_DATA_SOURCE); + verifyTableDoesntExist("kie_flyway_history_customers", TEST_DATA_SOURCE); + verifyTableDoesntExist("guitars", TEST_DATA_SOURCE); + verifyTableDoesntExist("kie_flyway_history_guitars", TEST_DATA_SOURCE); + } + + @Test + @Order(1) + public void testFlywayMigrationsWithExclusions() { + + testConfiguration.getModules().put("guitars", new TestKieFlywayNamedModule(false)); + + testClassLoader.addKieFlywayModule("initializers/kie-flyway.customers.properties"); + testClassLoader.addKieFlywayModule("initializers/kie-flyway.guitars.properties"); + + TestKieFlywayRunner.get(testConfiguration, testClassLoader) + .runFlyway(TEST_DATA_SOURCE.getDataSource()); + + validateKieFlywayIndex("customers", EXPECTED_CUSTOMERS_MIGRATIONS.stream().limit(3).toList(), TEST_DATA_SOURCE); + validateCustomersData(EXPECTED_CUSTOMERS.stream().limit(2).toList(), TEST_DATA_SOURCE); + + // Guitars module has been excluded, so it shouldn't be installed. Verifying that tables don't exist + verifyTableDoesntExist("guitars", TEST_DATA_SOURCE); + verifyTableDoesntExist("kie_flyway_history_guitars", TEST_DATA_SOURCE); + } + + @Test + @Order(2) + public void testFlywayMigrationsUpgrade() { + + testClassLoader.addKieFlywayModule("initializers/kie-flyway.customers2.properties"); + testClassLoader.addKieFlywayModule("initializers/kie-flyway.guitars.properties"); + + TestKieFlywayRunner.get(testConfiguration, testClassLoader) + .runFlyway(TEST_DATA_SOURCE.getDataSource()); + + validateKieFlywayIndex("customers", EXPECTED_CUSTOMERS_MIGRATIONS, TEST_DATA_SOURCE); + validateCustomersData(EXPECTED_CUSTOMERS, TEST_DATA_SOURCE); + + validateKieFlywayIndex("guitars", EXPECTED_GUITARS_MIGRATIONS, TEST_DATA_SOURCE); + validateGuitarsData(TEST_DATA_SOURCE); + } + + @AfterAll + public static void shutdown() { + TEST_DATA_SOURCE.shutDown(); + } + + public static class TestKieFlywayRunner extends KieFlywayRunner { + + protected TestKieFlywayRunner(KieFlywayConfiguration configuration, ClassLoader classLoader) { + super(configuration, classLoader); + } + + public static KieFlywayRunner get(TestKieFlywayConfiguration configuration, ClassLoader classLoader) { + return new TestKieFlywayRunner(configuration, classLoader); + } + } +} diff --git a/quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSource.java b/addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayConfiguration.java similarity index 52% rename from quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSource.java rename to addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayConfiguration.java index 9e0a7e8791f..1d20272a081 100644 --- a/quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSource.java +++ b/addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayConfiguration.java @@ -16,40 +16,32 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.kogito.persistence.quarkus; -import java.util.Map; -import java.util.Set; - -import org.eclipse.microprofile.config.spi.ConfigSource; +package org.kie.flyway.integration; -public class KogitoAddOnPersistenceJDBCConfigSource implements ConfigSource { +import java.util.Map; - static final Integer ORDINAL = 500; +public class TestKieFlywayConfiguration implements KieFlywayConfiguration { - private final Map configuration; + private boolean enabled; + private Map modules; - public KogitoAddOnPersistenceJDBCConfigSource(Map configuration) { - this.configuration = configuration; + public TestKieFlywayConfiguration(boolean enabled, Map modules) { + this.enabled = enabled; + this.modules = modules; } - @Override - public Set getPropertyNames() { - return configuration.keySet(); - } - - @Override - public int getOrdinal() { - return ORDINAL; + public void setEnabled(boolean enabled) { + this.enabled = enabled; } @Override - public String getValue(String propertyName) { - return configuration.get(propertyName); + public boolean isEnabled() { + return enabled; } @Override - public String getName() { - return KogitoAddOnPersistenceJDBCConfigSource.class.getSimpleName(); + public Map getModules() { + return modules; } } diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayNamedModule.java b/addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayNamedModule.java new file mode 100644 index 00000000000..8eea404acc1 --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/integration/TestKieFlywayNamedModule.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.integration; + +public class TestKieFlywayNamedModule implements KieFlywayNamedModule { + + private boolean enabled; + + public TestKieFlywayNamedModule(boolean enabled) { + this.enabled = enabled; + } + + @Override + public boolean isEnabled() { + return enabled; + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/AbstractKieFlywayTest.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/AbstractKieFlywayTest.java new file mode 100644 index 00000000000..3a6ff7fa3ff --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/AbstractKieFlywayTest.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Collection; + +import org.assertj.core.api.Assertions; +import org.kie.flyway.initializer.KieFlywayInitializerTest; +import org.kie.flyway.test.dataSources.TestDataSource; +import org.kie.flyway.test.models.Customer; +import org.kie.flyway.test.models.Guitar; +import org.kie.flyway.test.models.KieFlywayMigration; + +import static org.kie.flyway.test.models.TestModels.EXPECTED_GUITARS; + +public abstract class AbstractKieFlywayTest { + public static final String MODULE_MIGRATIONS_QUERY_TEMPLATE = "select \"version\", \"description\", \"success\" from \"kie_flyway_history_%s\" where \"version\" = ?"; + public static final String QUERY_CUSTOMERS_DATA = "select id, name, last_name, email from customers order by id"; + public static final String QUERY_GUITARS_DATA = "select id, brand, model, rating from guitars order by id"; + public static final String QUERY_QUERY_TABLE_EXISTS = "select count(*) as count from information_schema.tables where table_name = ?"; + + public void validateKieFlywayIndex(String moduleName, Collection expectedMigrations, TestDataSource dataSource) { + expectedMigrations.forEach(kieFlywayMigration -> validateFlywayMigration(moduleName, kieFlywayMigration, dataSource)); + } + + private void validateFlywayMigration(final String moduleName, final KieFlywayMigration migration, final TestDataSource dataSource) { + try (Connection con = dataSource.getDataSource().getConnection(); + PreparedStatement stmt = con.prepareStatement(KieFlywayInitializerTest.MODULE_MIGRATIONS_QUERY_TEMPLATE.formatted(moduleName));) { + stmt.setString(1, migration.version()); + try (ResultSet rs = stmt.executeQuery()) { + Assertions.assertThat(rs.next()) + .isTrue(); + Assertions.assertThat(rs.getString("version")) + .isEqualTo(migration.version()); + Assertions.assertThat(rs.getString("description")) + .isEqualTo(migration.description().formatted(dataSource.getDbType())); + Assertions.assertThat(rs.getBoolean("success")) + .isEqualTo(true); + Assertions.assertThat(rs.next()) + .isFalse(); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + protected void validateCustomersData(Collection expectedCustomers, TestDataSource dataSource) { + try (Connection con = dataSource.getDataSource().getConnection(); + PreparedStatement stmt = con.prepareStatement(KieFlywayInitializerTest.QUERY_CUSTOMERS_DATA); + ResultSet rs = stmt.executeQuery()) { + + for (Customer customer : expectedCustomers) { + Assertions.assertThat(rs.next()) + .isTrue(); + Assertions.assertThat(rs.getInt("id")) + .isEqualTo(customer.id()); + Assertions.assertThat(rs.getString("name")) + .isEqualTo(customer.name()); + Assertions.assertThat(rs.getString("last_name")) + .isEqualTo(customer.lastName()); + Assertions.assertThat(rs.getString("email")) + .isEqualTo(customer.email()); + } + Assertions.assertThat(rs.next()) + .isFalse(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + protected void validateGuitarsData(TestDataSource dataSource) { + try (Connection con = dataSource.getDataSource().getConnection(); + PreparedStatement stmt = con.prepareStatement(KieFlywayInitializerTest.QUERY_GUITARS_DATA); + ResultSet rs = stmt.executeQuery()) { + + for (Guitar guitar : EXPECTED_GUITARS) { + Assertions.assertThat(rs.next()) + .isTrue(); + Assertions.assertThat(rs.getInt("id")) + .isEqualTo(guitar.id()); + Assertions.assertThat(rs.getString("brand")) + .isEqualTo(guitar.brand()); + Assertions.assertThat(rs.getString("model")) + .isEqualTo(guitar.model()); + Assertions.assertThat(rs.getInt("rating")) + .isEqualTo(guitar.rating()); + } + + Assertions.assertThat(rs.next()) + .isFalse(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + protected void verifyTableDoesntExist(String tableName, TestDataSource dataSource) { + try (Connection con = dataSource.getDataSource().getConnection(); + PreparedStatement stmt = con.prepareStatement(QUERY_QUERY_TABLE_EXISTS);) { + stmt.setString(1, tableName); + try (ResultSet rs = stmt.executeQuery()) { + Assertions.assertThat(rs.next()).isTrue(); + Assertions.assertThat(rs.getInt("count")).isEqualTo(0); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/H2TestDataSource.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/H2TestDataSource.java new file mode 100644 index 00000000000..1b811681f6e --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/H2TestDataSource.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.dataSources; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.DataSource; + +import org.h2.jdbcx.JdbcDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class H2TestDataSource implements TestDataSource { + private static final Logger LOGGER = LoggerFactory.getLogger(H2TestDataSource.class); + + private final JdbcDataSource dataSource; + + public H2TestDataSource() { + dataSource = new JdbcDataSource(); + dataSource.setURL("jdbc:h2:mem:test_db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=true"); + dataSource.setUser("sa"); + dataSource.setPassword("sa"); + } + + @Override + public String getDbType() { + return "h2"; + } + + @Override + public DataSource getDataSource() { + return dataSource; + } + + @Override + public void shutDown() { + try (Connection con = dataSource.getConnection(); Statement stmt = con.createStatement()) { + stmt.execute("SHUTDOWN"); + } catch (SQLException e) { + LOGGER.warn("Error shutting down database", e); + } + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java new file mode 100644 index 00000000000..dc909d0fa54 --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.dataSources; + +import javax.sql.DataSource; + +import org.kie.kogito.testcontainers.KogitoPostgreSqlContainer; +import org.postgresql.ds.PGSimpleDataSource; + +public class PostgreSQLTestDataSource implements TestDataSource { + + private PGSimpleDataSource dataSource; + + public PostgreSQLTestDataSource(KogitoPostgreSqlContainer pgContainer) { + dataSource = new PGSimpleDataSource(); + dataSource.setUrl(pgContainer.getJdbcUrl()); + dataSource.setUser(pgContainer.getUsername()); + dataSource.setPassword(pgContainer.getPassword()); + } + + @Override + public String getDbType() { + return "postgresql"; + } + + @Override + public DataSource getDataSource() { + return dataSource; + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/TestDataSource.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/TestDataSource.java new file mode 100644 index 00000000000..0a0ecc6974c --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/TestDataSource.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.dataSources; + +import javax.sql.DataSource; + +public interface TestDataSource { + + String getDbType(); + + DataSource getDataSource(); + + default void shutDown() { + + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/models/Customer.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/Customer.java new file mode 100644 index 00000000000..607a7084a82 --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/Customer.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.models; + +public record Customer(Integer id, String name, String lastName, String email) { +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/models/Guitar.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/Guitar.java new file mode 100644 index 00000000000..f914b011938 --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/Guitar.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.models; + +public record Guitar(Integer id, String brand, String model, Integer rating) { +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/models/KieFlywayMigration.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/KieFlywayMigration.java new file mode 100644 index 00000000000..7df23f76a50 --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/KieFlywayMigration.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.models; + +public record KieFlywayMigration(String version, String description) { +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/models/TestModels.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/TestModels.java new file mode 100644 index 00000000000..8a13692ca2b --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/models/TestModels.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.models; + +import java.util.Arrays; +import java.util.Collection; + +public interface TestModels { + + static final Collection EXPECTED_CUSTOMERS_MIGRATIONS = Arrays.asList( + new KieFlywayMigration("1.0.0", "Create table %s"), + new KieFlywayMigration("1.0.1", "Alter table %s"), + new KieFlywayMigration("1.0.2", "Insert book characters %s"), + new KieFlywayMigration("1.0.5", "Insert game characters %s")); + + static final Collection EXPECTED_CUSTOMERS = Arrays.asList(new Customer(1, "Ned", "Stark", "n.stark@winterfell.book"), + new Customer(2, "Ender", "Wiggin", "ender@endersgame.book"), + new Customer(3, "Guybrush", "Threepwood", "guybrush@monkeyisland.game"), + new Customer(4, "Herman", "Toothrot", "toothrot@monkeyisland.game")); + + static final Collection EXPECTED_GUITARS_MIGRATIONS = Arrays.asList( + new KieFlywayMigration("1.0.0", "Create guitars table %s"), + new KieFlywayMigration("1.0.1", "Alter guitars table %s"), + new KieFlywayMigration("1.0.2", "Insert fender guitars %s"), + new KieFlywayMigration("1.0.5", "Insert gibson guitars %s")); + + static final Collection EXPECTED_GUITARS = Arrays.asList(new Guitar(1, "Fender", "Telecaster", 10), + new Guitar(2, "Fender", "Stratocaster", 9), + new Guitar(3, "Fender", "Jazzmaster", 7), + new Guitar(4, "Gibson", "SG", 9), + new Guitar(5, "Gibson", "Les Paul", 9), + new Guitar(6, "Gibson", "ES-330", 10)); +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/utils/TestClassLoader.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/utils/TestClassLoader.java new file mode 100644 index 00000000000..7b55cd237fe --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/utils/TestClassLoader.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.test.utils; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import org.kie.flyway.initializer.impl.DefaultKieModuleFlywayConfigLoader; + +public class TestClassLoader extends ClassLoader { + private final List modules = new ArrayList<>(); + + public TestClassLoader(ClassLoader parent) { + super(parent); + } + + public void addKieFlywayModule(String resourceUrl) { + this.modules.add(getResource(resourceUrl)); + } + + @Override + public Stream resources(String name) { + if (!modules.isEmpty() && DefaultKieModuleFlywayConfigLoader.KIE_FLYWAY_DESCRIPTOR_FILE_LOCATION.equals(name)) { + return modules.stream(); + } + return super.resources(name); + } +} diff --git a/addons/common/flyway/src/test/resources/META-INF/kie-flyway.properties b/addons/common/flyway/src/test/resources/META-INF/kie-flyway.properties new file mode 100644 index 00000000000..a4f89f2416d --- /dev/null +++ b/addons/common/flyway/src/test/resources/META-INF/kie-flyway.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=test + +module.locations.h2=classpath:kie-flyway/db/test/h2 +module.locations.postgresql=classpath:kie-flyway/db/test/postgresql +module.locations.default=classpath:kie-flyway/db/test/ansi \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.customers.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.customers.properties new file mode 100644 index 00000000000..ad55f01d8e2 --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.customers.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=customers + +module.locations.h2=classpath:kie-flyway/db/customers/h2 +module.locations.postgresql=classpath:kie-flyway/db/customers/postgresql +module.locations.default=classpath:kie-flyway/db/customers/ansi \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.customers2.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.customers2.properties new file mode 100644 index 00000000000..11cc64b3c89 --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.customers2.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=customers + +module.locations.h2=classpath:kie-flyway/db/customers/h2,classpath:kie-flyway/db/customers-2/h2 +module.locations.postgresql=classpath:kie-flyway/db/customers/postgresql,classpath:kie-flyway/db/customers-2/postgresql +module.locations.default=classpath:kie-flyway/db/customers/ansi,classpath:kie-flyway/db/customers-2/ansi \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated1.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated1.properties new file mode 100644 index 00000000000..c5b21d77a5e --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated1.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=test-duplicated-1 + +module.locations.h2=classpath:kie-flyway/db/test/h2 +module.locations.postgresql=classpath:kie-flyway/db/test/postgresql +module.locations.default=classpath:kie-flyway/db/test/ansi \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated2.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated2.properties new file mode 100644 index 00000000000..7ca37ee74f0 --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.duplicated2.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=test-duplicated-2 + +module.locations.h2=classpath:kie-flyway/db/test/h2 +module.locations.postgresql=classpath:kie-flyway/db/test/postgresql +module.locations.default=classpath:kie-flyway/db/test/ansi \ No newline at end of file diff --git a/quarkus/addons/persistence/jdbc/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory b/addons/common/flyway/src/test/resources/initializers/kie-flyway.empty.properties similarity index 90% rename from quarkus/addons/persistence/jdbc/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory rename to addons/common/flyway/src/test/resources/initializers/kie-flyway.empty.properties index 0ce6025b8aa..d8a500d9d8d 100644 --- a/quarkus/addons/persistence/jdbc/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.empty.properties @@ -17,4 +17,3 @@ # under the License. # -org.kie.kogito.persistence.quarkus.KogitoAddOnPersistenceJDBCConfigSourceFactory diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars.properties new file mode 100644 index 00000000000..3663d80f6ee --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=guitars + +module.locations.h2=classpath:kie-flyway/db/guitars/h2 +module.locations.postgresql=classpath:kie-flyway/db/guitars/postgresql +module.locations.default=classpath:kie-flyway/db/guitars/ansi \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars_default.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars_default.properties new file mode 100644 index 00000000000..2328c545a71 --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.guitars_default.properties @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=guitars + +module.locations.postgresql=classpath:kie-flyway/db/guitars/postgresql +module.locations.default=classpath:kie-flyway/db/guitars/h2 \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.no.locations.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.no.locations.properties new file mode 100644 index 00000000000..62dc592d7d1 --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.no.locations.properties @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=no-locations \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/initializers/kie-flyway.wrong.format.properties b/addons/common/flyway/src/test/resources/initializers/kie-flyway.wrong.format.properties new file mode 100644 index 00000000000..157c346edde --- /dev/null +++ b/addons/common/flyway/src/test/resources/initializers/kie-flyway.wrong.format.properties @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=test-wrong-format + +module.locations.h2.default=this won't work \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/ansi/V1.0.5__Insert_game_characters_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/ansi/V1.0.5__Insert_game_characters_ansi.sql new file mode 100644 index 00000000000..fdc120933e0 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/ansi/V1.0.5__Insert_game_characters_ansi.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into customers (id, name, last_name, email) values (3, 'Guybrush', 'Threepwood', 'guybrush@monkeyisland.game'); +insert into customers (id, name, last_name, email) values (4, 'Herman', 'Toothrot', 'toothrot@monkeyisland.game'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/h2/V1.0.5__Insert_game_characters_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/h2/V1.0.5__Insert_game_characters_h2.sql new file mode 100644 index 00000000000..fdc120933e0 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/h2/V1.0.5__Insert_game_characters_h2.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into customers (id, name, last_name, email) values (3, 'Guybrush', 'Threepwood', 'guybrush@monkeyisland.game'); +insert into customers (id, name, last_name, email) values (4, 'Herman', 'Toothrot', 'toothrot@monkeyisland.game'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/postgresql/V1.0.5__Insert_game_characters_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/postgresql/V1.0.5__Insert_game_characters_postgresql.sql new file mode 100644 index 00000000000..fdc120933e0 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers-2/postgresql/V1.0.5__Insert_game_characters_postgresql.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into customers (id, name, last_name, email) values (3, 'Guybrush', 'Threepwood', 'guybrush@monkeyisland.game'); +insert into customers (id, name, last_name, email) values (4, 'Herman', 'Toothrot', 'toothrot@monkeyisland.game'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.0__Create_table_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.0__Create_table_ansi.sql new file mode 100644 index 00000000000..9783fb1f16c --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.0__Create_table_ansi.sql @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table customers +( + id bigint not null, + name varchar(128) not null, + last_name varchar(128) not null, + constraint customers_pk primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.1__Alter_table_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.1__Alter_table_ansi.sql new file mode 100644 index 00000000000..bda9e5e58bb --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.1__Alter_table_ansi.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table customers add column email varchar(128); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.2__Insert_book_characters_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.2__Insert_book_characters_ansi.sql new file mode 100644 index 00000000000..6702a0c4c01 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/ansi/V1.0.2__Insert_book_characters_ansi.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into customers (id, name, last_name, email) values (1, 'Ned', 'Stark', 'n.stark@winterfell.book'); +insert into customers (id, name, last_name, email) values (2, 'Ender', 'Wiggin', 'ender@endersgame.book'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.0__Create_table_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.0__Create_table_h2.sql new file mode 100644 index 00000000000..9783fb1f16c --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.0__Create_table_h2.sql @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table customers +( + id bigint not null, + name varchar(128) not null, + last_name varchar(128) not null, + constraint customers_pk primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.1__Alter_table_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.1__Alter_table_h2.sql new file mode 100644 index 00000000000..bda9e5e58bb --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.1__Alter_table_h2.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table customers add column email varchar(128); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.2__Insert_book_characters_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.2__Insert_book_characters_h2.sql new file mode 100644 index 00000000000..6702a0c4c01 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/h2/V1.0.2__Insert_book_characters_h2.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into customers (id, name, last_name, email) values (1, 'Ned', 'Stark', 'n.stark@winterfell.book'); +insert into customers (id, name, last_name, email) values (2, 'Ender', 'Wiggin', 'ender@endersgame.book'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.0__Create_table_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.0__Create_table_postgresql.sql new file mode 100644 index 00000000000..9783fb1f16c --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.0__Create_table_postgresql.sql @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table customers +( + id bigint not null, + name varchar(128) not null, + last_name varchar(128) not null, + constraint customers_pk primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.1__Alter_table_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.1__Alter_table_postgresql.sql new file mode 100644 index 00000000000..bda9e5e58bb --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.1__Alter_table_postgresql.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table customers add column email varchar(128); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.2__Insert_book_characters_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.2__Insert_book_characters_postgresql.sql new file mode 100644 index 00000000000..6702a0c4c01 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/customers/postgresql/V1.0.2__Insert_book_characters_postgresql.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into customers (id, name, last_name, email) values (1, 'Ned', 'Stark', 'n.stark@winterfell.book'); +insert into customers (id, name, last_name, email) values (2, 'Ender', 'Wiggin', 'ender@endersgame.book'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.0__Create_guitars_table_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.0__Create_guitars_table_ansi.sql new file mode 100644 index 00000000000..dbbc6788e06 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.0__Create_guitars_table_ansi.sql @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table guitars +( + id bigint not null, + brand varchar(128) not null, + model varchar(128) not null, + constraint guitars_pk primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.1__Alter_guitars_table_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.1__Alter_guitars_table_ansi.sql new file mode 100644 index 00000000000..e7b1e28c61a --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.1__Alter_guitars_table_ansi.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table guitars add column rating bigint not null; \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.2__Insert_fender_guitars_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.2__Insert_fender_guitars_ansi.sql new file mode 100644 index 00000000000..38ca843c4fd --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.2__Insert_fender_guitars_ansi.sql @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into guitars (id, brand, model, rating) values (1, 'Fender', 'Telecaster', 10); +insert into guitars (id, brand, model, rating) values (2, 'Fender', 'Stratocaster', 9); +insert into guitars (id, brand, model, rating) values (3, 'Fender', 'Jazzmaster', 7); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.5__Insert_gibson_guitars_ansi.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.5__Insert_gibson_guitars_ansi.sql new file mode 100644 index 00000000000..b96b93d98b5 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/ansi/V1.0.5__Insert_gibson_guitars_ansi.sql @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into guitars (id, brand, model, rating) values (4, 'Gibson', 'SG', 9); +insert into guitars (id, brand, model, rating) values (5, 'Gibson', 'Les Paul', 9); +insert into guitars (id, brand, model, rating) values (6, 'Gibson', 'ES-330', 10); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.0__Create_guitars_table_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.0__Create_guitars_table_h2.sql new file mode 100644 index 00000000000..3a4ce512576 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.0__Create_guitars_table_h2.sql @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table guitars +( + id bigint not null, + brand varchar(128) not null, + model varchar(128) not null, + constraint guitars_pk primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.1__Alter_guitars_table_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.1__Alter_guitars_table_h2.sql new file mode 100644 index 00000000000..e7b1e28c61a --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.1__Alter_guitars_table_h2.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table guitars add column rating bigint not null; \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.2__Insert_fender_guitars_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.2__Insert_fender_guitars_h2.sql new file mode 100644 index 00000000000..38ca843c4fd --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.2__Insert_fender_guitars_h2.sql @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into guitars (id, brand, model, rating) values (1, 'Fender', 'Telecaster', 10); +insert into guitars (id, brand, model, rating) values (2, 'Fender', 'Stratocaster', 9); +insert into guitars (id, brand, model, rating) values (3, 'Fender', 'Jazzmaster', 7); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.5__Insert_gibson_guitars_h2.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.5__Insert_gibson_guitars_h2.sql new file mode 100644 index 00000000000..b96b93d98b5 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/h2/V1.0.5__Insert_gibson_guitars_h2.sql @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into guitars (id, brand, model, rating) values (4, 'Gibson', 'SG', 9); +insert into guitars (id, brand, model, rating) values (5, 'Gibson', 'Les Paul', 9); +insert into guitars (id, brand, model, rating) values (6, 'Gibson', 'ES-330', 10); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.0__Create_guitars_table_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.0__Create_guitars_table_postgresql.sql new file mode 100644 index 00000000000..3a4ce512576 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.0__Create_guitars_table_postgresql.sql @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table guitars +( + id bigint not null, + brand varchar(128) not null, + model varchar(128) not null, + constraint guitars_pk primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.1__Alter_guitars_table_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.1__Alter_guitars_table_postgresql.sql new file mode 100644 index 00000000000..e7b1e28c61a --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.1__Alter_guitars_table_postgresql.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table guitars add column rating bigint not null; \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.2__Insert_fender_guitars_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.2__Insert_fender_guitars_postgresql.sql new file mode 100644 index 00000000000..38ca843c4fd --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.2__Insert_fender_guitars_postgresql.sql @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into guitars (id, brand, model, rating) values (1, 'Fender', 'Telecaster', 10); +insert into guitars (id, brand, model, rating) values (2, 'Fender', 'Stratocaster', 9); +insert into guitars (id, brand, model, rating) values (3, 'Fender', 'Jazzmaster', 7); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.5__Insert_gibson_guitars_postgresql.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.5__Insert_gibson_guitars_postgresql.sql new file mode 100644 index 00000000000..b96b93d98b5 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/guitars/postgresql/V1.0.5__Insert_gibson_guitars_postgresql.sql @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into guitars (id, brand, model, rating) values (4, 'Gibson', 'SG', 9); +insert into guitars (id, brand, model, rating) values (5, 'Gibson', 'Les Paul', 9); +insert into guitars (id, brand, model, rating) values (6, 'Gibson', 'ES-330', 10); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.0__Create_table.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.0__Create_table.sql new file mode 100644 index 00000000000..ed8eb3013b6 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.0__Create_table.sql @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table test_table +( + id bigint not null, + message varchar(128) not null, + constraint test_table_pkey primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.1__Alter_table.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.1__Alter_table.sql new file mode 100644 index 00000000000..a7fd7a59b2c --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.1__Alter_table.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table test_table add column dbtype varchar(128); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.2__Insert_data.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.2__Insert_data.sql new file mode 100644 index 00000000000..de9448fc686 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/ansi/V1.0.2__Insert_data.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into test_table (id, message, dbtype) +values (1, 'Hello from Kie Flyway - test', 'ansi'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.0__Create_table.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.0__Create_table.sql new file mode 100644 index 00000000000..ed8eb3013b6 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.0__Create_table.sql @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table test_table +( + id bigint not null, + message varchar(128) not null, + constraint test_table_pkey primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.1__Alter_table.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.1__Alter_table.sql new file mode 100644 index 00000000000..a7fd7a59b2c --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.1__Alter_table.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table test_table add column dbtype varchar(128); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.2__Insert_data.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.2__Insert_data.sql new file mode 100644 index 00000000000..8c169053040 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/h2/V1.0.2__Insert_data.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into test_table (id, message, dbtype) +values (1, 'Hello from Kie Flyway - test', 'H2'); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.0__Create_table.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.0__Create_table.sql new file mode 100644 index 00000000000..ed8eb3013b6 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.0__Create_table.sql @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +create table test_table +( + id bigint not null, + message varchar(128) not null, + constraint test_table_pkey primary key (id) +); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.1__Alter_table.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.1__Alter_table.sql new file mode 100644 index 00000000000..a7fd7a59b2c --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.1__Alter_table.sql @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +alter table test_table add column dbtype varchar(128); \ No newline at end of file diff --git a/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.2__Insert_data.sql b/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.2__Insert_data.sql new file mode 100644 index 00000000000..258edf6a7f6 --- /dev/null +++ b/addons/common/flyway/src/test/resources/kie-flyway/db/test/postgresql/V1.0.2__Insert_data.sql @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +insert into test_table (id, message, dbtype) +values (1, 'Hello from Kie Flyway - test', 'postgresql'); \ No newline at end of file diff --git a/addons/common/persistence/ddl/src/assembly/db-scripts.xml b/addons/common/persistence/ddl/src/assembly/db-scripts.xml index 6055cb3e26f..4033e889b78 100644 --- a/addons/common/persistence/ddl/src/assembly/db-scripts.xml +++ b/addons/common/persistence/ddl/src/assembly/db-scripts.xml @@ -28,21 +28,14 @@ false - ${path.to.persistence.modules}/jdbc/src/main/resources/db/postgresql + ${path.to.persistence.modules}/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql postgresql *.sql - ${path.to.persistence.modules}/jdbc/src/main/resources/db/oracle - oracle - - *.sql - - - - ${path.to.persistence.modules}/jdbc/src/main/resources/db/ansi + ${path.to.persistence.modules}/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi ansi *.sql diff --git a/addons/common/persistence/ddl/src/assembly/productized-db-scripts.xml b/addons/common/persistence/ddl/src/assembly/productized-db-scripts.xml index e036f138991..39ec204674d 100644 --- a/addons/common/persistence/ddl/src/assembly/productized-db-scripts.xml +++ b/addons/common/persistence/ddl/src/assembly/productized-db-scripts.xml @@ -28,7 +28,7 @@ false - ${path.to.persistence.modules}/jdbc/src/main/resources/db/postgresql + ${path.to.persistence.modules}/jdbc/src/main/resources/kie-flyway/db/postgresql postgresql *.sql diff --git a/addons/common/persistence/jdbc/pom.xml b/addons/common/persistence/jdbc/pom.xml index aac9886605c..b0fe68f133b 100644 --- a/addons/common/persistence/jdbc/pom.xml +++ b/addons/common/persistence/jdbc/pom.xml @@ -83,9 +83,8 @@ test - org.flywaydb - flyway-core - ${version.org.flywaydb} + org.kie + kie-addons-flyway test diff --git a/addons/common/persistence/jdbc/src/main/resources/META-INF/kie-flyway.properties b/addons/common/persistence/jdbc/src/main/resources/META-INF/kie-flyway.properties new file mode 100644 index 00000000000..a2a0dccd062 --- /dev/null +++ b/addons/common/persistence/jdbc/src/main/resources/META-INF/kie-flyway.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +module.name=runtime-persistence + +module.locations.default=classpath:kie-flyway/db/persistence-jdbc/ansi +module.locations.postgresql=classpath:kie-flyway/db/persistence-jdbc/postgresql +module.locations.h2=classpath:kie-flyway/db/persistence-jdbc/ansi \ No newline at end of file diff --git a/addons/common/persistence/jdbc/src/main/resources/db/ansi/V1.35.0__create_runtime_ansi.sql b/addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi/V1.35.0__create_runtime_ansi.sql similarity index 100% rename from addons/common/persistence/jdbc/src/main/resources/db/ansi/V1.35.0__create_runtime_ansi.sql rename to addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi/V1.35.0__create_runtime_ansi.sql diff --git a/addons/common/persistence/jdbc/src/main/resources/db/ansi/V10.0.0__add_business_key_ansi.sql b/addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi/V10.0.0__add_business_key_ansi.sql similarity index 100% rename from addons/common/persistence/jdbc/src/main/resources/db/ansi/V10.0.0__add_business_key_ansi.sql rename to addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi/V10.0.0__add_business_key_ansi.sql diff --git a/addons/common/persistence/jdbc/src/main/resources/db/ansi/V10.0.1__create_correlation_ansi.sql b/addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi/V10.0.1__create_correlation_ansi.sql similarity index 100% rename from addons/common/persistence/jdbc/src/main/resources/db/ansi/V10.0.1__create_correlation_ansi.sql rename to addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/ansi/V10.0.1__create_correlation_ansi.sql diff --git a/addons/common/persistence/jdbc/src/main/resources/db/postgresql/V1.35.0__create_runtime_PostgreSQL.sql b/addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql/V1.35.0__create_runtime_PostgreSQL.sql similarity index 100% rename from addons/common/persistence/jdbc/src/main/resources/db/postgresql/V1.35.0__create_runtime_PostgreSQL.sql rename to addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql/V1.35.0__create_runtime_PostgreSQL.sql diff --git a/addons/common/persistence/jdbc/src/main/resources/db/postgresql/V10.0.0__add_business_key_PostgreSQL.sql b/addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql/V10.0.0__add_business_key_PostgreSQL.sql similarity index 100% rename from addons/common/persistence/jdbc/src/main/resources/db/postgresql/V10.0.0__add_business_key_PostgreSQL.sql rename to addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql/V10.0.0__add_business_key_PostgreSQL.sql diff --git a/addons/common/persistence/jdbc/src/main/resources/db/postgresql/V10.0.1__alter_correlation_PostgreSQL.sql b/addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql/V10.0.1__alter_correlation_PostgreSQL.sql similarity index 100% rename from addons/common/persistence/jdbc/src/main/resources/db/postgresql/V10.0.1__alter_correlation_PostgreSQL.sql rename to addons/common/persistence/jdbc/src/main/resources/kie-flyway/db/persistence-jdbc/postgresql/V10.0.1__alter_correlation_PostgreSQL.sql diff --git a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java index 981114c5df7..2f4355beffa 100644 --- a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java +++ b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java @@ -26,8 +26,8 @@ import javax.sql.DataSource; import org.drools.io.ClassPathResource; -import org.flywaydb.core.Flyway; import org.junit.jupiter.api.Test; +import org.kie.flyway.initializer.KieFlywayInitializer; import org.kie.kogito.auth.IdentityProviders; import org.kie.kogito.auth.SecurityPolicy; import org.kie.kogito.internal.process.workitem.Policy; @@ -40,7 +40,6 @@ import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig; import org.kie.kogito.process.impl.StaticProcessConfig; import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler; -import org.testcontainers.containers.JdbcDatabaseContainer; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; @@ -62,14 +61,11 @@ abstract class AbstractProcessInstancesIT { public static final String TEST_ID = "02ac3854-46ee-42b7-8b63-5186c9889d96"; public static Policy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john")); - DataSource dataSource; - - public static void initMigration(JdbcDatabaseContainer container, String dbKind) { - Flyway flyway = Flyway.configure().dataSource(container.getJdbcUrl(), - container.getUsername(), - container.getPassword()) - .locations("classpath:db/" + dbKind).load(); - flyway.migrate(); + public static void initMigration(DataSource dataSource) { + KieFlywayInitializer.builder() + .withDatasource(dataSource) + .build() + .migrate(); } public static BpmnProcess createProcess(TestProcessInstancesFactory factory, String fileName) { diff --git a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/PostgreSqlProcessInstancesIT.java b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/PostgreSqlProcessInstancesIT.java index 3840a9c4303..3092f427897 100644 --- a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/PostgreSqlProcessInstancesIT.java +++ b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/PostgreSqlProcessInstancesIT.java @@ -39,7 +39,7 @@ public static void start() { PG_DATA_SOURCE.setUrl(PG_CONTAINER.getJdbcUrl()); PG_DATA_SOURCE.setUser(PG_CONTAINER.getUsername()); PG_DATA_SOURCE.setPassword(PG_CONTAINER.getPassword()); - initMigration(PG_CONTAINER, "postgresql"); + initMigration(PG_DATA_SOURCE); } protected DataSource getDataSource() { diff --git a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/correlation/JDBCCorrelationServiceIT.java b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/correlation/JDBCCorrelationServiceIT.java index 62212ac0eb0..212e41e226a 100644 --- a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/correlation/JDBCCorrelationServiceIT.java +++ b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/correlation/JDBCCorrelationServiceIT.java @@ -21,16 +21,17 @@ import java.util.Collections; import java.util.Optional; -import org.flywaydb.core.Flyway; +import javax.sql.DataSource; + import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.kie.flyway.initializer.KieFlywayInitializer; import org.kie.kogito.correlation.CompositeCorrelation; import org.kie.kogito.correlation.CorrelationInstance; import org.kie.kogito.correlation.SimpleCorrelation; import org.kie.kogito.persistence.jdbc.correlation.JDBCCorrelationService; import org.kie.kogito.testcontainers.KogitoPostgreSqlContainer; import org.postgresql.ds.PGSimpleDataSource; -import org.testcontainers.containers.JdbcDatabaseContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -51,17 +52,14 @@ public static void setUp() { dataSource.setUser(PG_CONTAINER.getUsername()); dataSource.setPassword(PG_CONTAINER.getPassword()); correlationService = new JDBCCorrelationService(dataSource); - //create table - // DDLRunner.init(new GenericRepository(dataSource), true); - initMigration(PG_CONTAINER, "postgresql"); + initMigration(dataSource); } - public static void initMigration(JdbcDatabaseContainer container, String dbKind) { - Flyway flyway = Flyway.configure().dataSource(container.getJdbcUrl(), - container.getUsername(), - container.getPassword()) - .locations("classpath:db/" + dbKind).load(); - flyway.migrate(); + public static void initMigration(DataSource dataSource) { + KieFlywayInitializer.builder() + .withDatasource(dataSource) + .build() + .migrate(); } @Test diff --git a/addons/common/persistence/postgresql/.gitignore b/addons/common/persistence/postgresql/.gitignore index acccaf1ecb3..423a2b902f1 100644 --- a/addons/common/persistence/postgresql/.gitignore +++ b/addons/common/persistence/postgresql/.gitignore @@ -17,4 +17,4 @@ # under the License. ### -src/main/resources/db/migration/* \ No newline at end of file +/src/main/resources/kie-flyway/db/persistence-postgresql/postgresql/* \ No newline at end of file diff --git a/addons/common/persistence/postgresql/pom.xml b/addons/common/persistence/postgresql/pom.xml index ee2df9c829f..581d6edf9f2 100644 --- a/addons/common/persistence/postgresql/pom.xml +++ b/addons/common/persistence/postgresql/pom.xml @@ -1,4 +1,4 @@ - org.kie.kogito @@ -1720,6 +1732,42 @@ sources + + + org.kie + kie-addons-flyway + ${project.version} + + + org.kie + kie-addons-flyway + ${project.version} + sources + + + org.kie + kie-addons-quarkus-flyway + ${project.version} + + + org.kie + kie-addons-quarkus-flyway + ${project.version} + sources + + + org.kie + kie-addons-quarkus-flyway-deployment + ${project.version} + + + org.kie + kie-addons-quarkus-flyway-deployment + ${project.version} + sources + + + org.kie.kogito diff --git a/kogito-build/kogito-dependencies-bom/pom.xml b/kogito-build/kogito-dependencies-bom/pom.xml index e0a87af2f99..0c815fc2353 100644 --- a/kogito-build/kogito-dependencies-bom/pom.xml +++ b/kogito-build/kogito-dependencies-bom/pom.xml @@ -82,6 +82,7 @@ 1.12.2 9.22.3 42.7.2 + 2.2.220 4.0.5.Final 3.10.0 @@ -376,6 +377,11 @@ postgresql ${version.org.postgresql} + + com.h2database + h2 + ${version.com.h2} + io.smallrye smallrye-open-api-core @@ -700,6 +706,13 @@ ${version.io.swagger.core.v3} + + + org.flywaydb + flyway-core + ${version.org.flywaydb} + + org.infinispan diff --git a/kogito-test-utils/src/main/java/org/kie/kogito/testcontainers/KogitoPostgreSqlContainer.java b/kogito-test-utils/src/main/java/org/kie/kogito/testcontainers/KogitoPostgreSqlContainer.java index 2c284e60746..b631bf23c72 100644 --- a/kogito-test-utils/src/main/java/org/kie/kogito/testcontainers/KogitoPostgreSqlContainer.java +++ b/kogito-test-utils/src/main/java/org/kie/kogito/testcontainers/KogitoPostgreSqlContainer.java @@ -27,6 +27,8 @@ import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; +import org.testcontainers.containers.wait.strategy.WaitAllStrategy; /** * PostgreSQL Container for Kogito examples. @@ -42,6 +44,15 @@ public KogitoPostgreSqlContainer() { withLogConsumer(getLogger()); withLogConsumer(new Slf4jLogConsumer(LOGGER)); withStartupTimeout(Constants.CONTAINER_START_TIMEOUT); + + /* + * Overriding default waitStrategy (LogMessageWaitStrategy) added by the parent to also wait for the mapped port to be available. This ensures that the PostgreSQLContainer is running + * and the mapped ports are ready before running any test. + * This avoids connection issues with the container when using container managers that do the port mapping after the container has started. + */ + this.waitStrategy = new WaitAllStrategy() + .withStrategy(this.waitStrategy) + .withStrategy(new HostPortWaitStrategy()); } private Consumer getLogger() { diff --git a/quarkus/addons/flyway/deployment/pom.xml b/quarkus/addons/flyway/deployment/pom.xml new file mode 100644 index 00000000000..1e6eefccdc8 --- /dev/null +++ b/quarkus/addons/flyway/deployment/pom.xml @@ -0,0 +1,81 @@ + + + + 4.0.0 + + org.kie + kie-addons-quarkus-flyway-parent + 999-SNAPSHOT + + kie-addons-quarkus-flyway-deployment + Kie :: Add-Ons :: Quarkus :: Flyway :: Deployment + + + org.kie.flyway.quarkus.deployment + + + + + + org.kie + kie-addons-quarkus-flyway + + + org.kie + kogito-addons-quarkus-common-deployment + + + io.quarkus + quarkus-arc-deployment + + + io.quarkus + quarkus-agroal-deployment + + + + org.mockito + mockito-junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${version.io.quarkus} + + + + + + + diff --git a/quarkus/addons/flyway/deployment/src/main/java/org/kie/flyway/quarkus/deployment/KieFlywayExtensionProcessor.java b/quarkus/addons/flyway/deployment/src/main/java/org/kie/flyway/quarkus/deployment/KieFlywayExtensionProcessor.java new file mode 100644 index 00000000000..5ec08518986 --- /dev/null +++ b/quarkus/addons/flyway/deployment/src/main/java/org/kie/flyway/quarkus/deployment/KieFlywayExtensionProcessor.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.flyway.quarkus.deployment; + +import java.util.List; +import java.util.Optional; + +import org.kie.flyway.quarkus.KieFlywayQuarkusRecorder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.quarkus.agroal.spi.JdbcDataSourceBuildItem; +import io.quarkus.arc.deployment.BeanContainerBuildItem; +import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem; +import io.quarkus.deployment.annotations.*; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.FeatureBuildItem; + +public class KieFlywayExtensionProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(KieFlywayExtensionProcessor.class); + + private static final String FEATURE = "kie-flyway"; + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } + + @BuildStep + @Consume(BeanContainerBuildItem.class) + @Consume(JdbcDataSourceBuildItem.class) + @Produce(SyntheticBeansRuntimeInitBuildItem.class) + @Record(ExecutionTime.RUNTIME_INIT) + void runMigration( + KieFlywayQuarkusRecorder recorder, + List jdbcDataSourceBuildItems) { + + Optional jdbcDataSourceOptional = jdbcDataSourceBuildItems.stream() + .filter(JdbcDataSourceBuildItem::isDefault) + .findFirst(); + + if (jdbcDataSourceOptional.isEmpty()) { + LOGGER.warn("KIE Flyway: No default DataSource defined, Skipping KIE Flyway..."); + return; + } + + JdbcDataSourceBuildItem jdbcDataSource = jdbcDataSourceOptional.get(); + recorder.run(jdbcDataSource.getName()); + } +} diff --git a/quarkus/addons/flyway/pom.xml b/quarkus/addons/flyway/pom.xml new file mode 100644 index 00000000000..8d225364a8b --- /dev/null +++ b/quarkus/addons/flyway/pom.xml @@ -0,0 +1,39 @@ + + + + 4.0.0 + + org.kie + kogito-addons-quarkus-parent + 999-SNAPSHOT + + + kie-addons-quarkus-flyway-parent + Kie :: Add-Ons :: Quarkus :: Flyway :: Parent + pom + + + runtime + deployment + + + diff --git a/quarkus/addons/flyway/runtime/pom.xml b/quarkus/addons/flyway/runtime/pom.xml new file mode 100644 index 00000000000..3190d2cbf8b --- /dev/null +++ b/quarkus/addons/flyway/runtime/pom.xml @@ -0,0 +1,93 @@ + + + + 4.0.0 + + org.kie + kie-addons-quarkus-flyway-parent + 999-SNAPSHOT + + kie-addons-quarkus-flyway + Kie :: Add-Ons :: Quarkus :: Flyway :: Runtime + + + org.kie.flyway.quarkus.runtime + + + + + jakarta.enterprise + jakarta.enterprise.cdi-api + + + io.quarkus + quarkus-core + + + io.quarkus + quarkus-agroal + + + io.quarkus + quarkus-builder + + + org.kie + kie-addons-flyway + + + + + + + io.quarkus + quarkus-extension-maven-plugin + ${version.io.quarkus} + + + compile + + extension-descriptor + + + ${project.groupId}:${project.artifactId}-deployment:${project.version} + + org.kie.addons.flyway + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${version.io.quarkus} + + + + + + + diff --git a/quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRecorder.java b/quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRecorder.java new file mode 100644 index 00000000000..13d4c841610 --- /dev/null +++ b/quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRecorder.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.quarkus; + +import javax.sql.DataSource; + +import org.kie.flyway.integration.KieFlywayRunner; + +import io.quarkus.agroal.runtime.DataSources; +import io.quarkus.arc.Arc; +import io.quarkus.runtime.RuntimeValue; +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class KieFlywayQuarkusRecorder { + + private final RuntimeValue config; + + public KieFlywayQuarkusRecorder(RuntimeValue config) { + this.config = config; + } + + public void run(String defaultDSName) { + + DataSources agroalDatasourceS = Arc.container().select(DataSources.class).get(); + DataSource dataSource = agroalDatasourceS.getDataSource(defaultDSName); + + KieFlywayRunner.get(config.getValue()) + .runFlyway(dataSource); + } +} diff --git a/quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRuntimeConfig.java b/quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRuntimeConfig.java new file mode 100644 index 00000000000..3f79c9643e5 --- /dev/null +++ b/quarkus/addons/flyway/runtime/src/main/java/org/kie/flyway/quarkus/KieFlywayQuarkusRuntimeConfig.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.quarkus; + +import java.util.Map; + +import org.kie.flyway.integration.KieFlywayConfiguration; +import org.kie.flyway.integration.KieFlywayNamedModule; + +import io.quarkus.runtime.annotations.*; + +/** + * Configuration for the Kie Flyway initializer + */ +@ConfigRoot(prefix = "kie", name = "flyway", phase = ConfigPhase.RUN_TIME) +public class KieFlywayQuarkusRuntimeConfig implements KieFlywayConfiguration { + + /** + * Enables the execution of the Flyway initializer during the application startup + */ + @ConfigItem(name = "enabled", defaultValue = "true") + boolean enabled; + + /** + * List of {@link KieQuarkusFlywayNamedModule} that allow to enable or disable a given modul + */ + @ConfigItem(name = "modules") + Map modules; + + @Override + public boolean isEnabled() { + return enabled; + } + + @Override + public Map getModules() { + return modules; + } + + @ConfigGroup + public static class KieQuarkusFlywayNamedModule implements KieFlywayNamedModule { + + /** + * Enables the execution of the Flyway initializer for a specific Kie module + */ + @ConfigItem(name = "enabled", defaultValue = "true") + boolean enabled; + + @Override + public boolean isEnabled() { + return enabled; + } + } +} diff --git a/quarkus/addons/flyway/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/quarkus/addons/flyway/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 00000000000..45009838096 --- /dev/null +++ b/quarkus/addons/flyway/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,36 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +name: KIE Flyway Add-On +description: Add-On that enables other addons to initialize their DB using Flyway +metadata: + keywords: + - KIE + - Flyway + - persistence + - jdbc + guide: https://quarkus.io/guides/kie + categories: + - "business-automation" + - "cloud" + - "flyway" + - "persistence" + status: "stable" + config: + - "kie.flyway" diff --git a/quarkus/addons/flyway/runtime/src/main/resources/application.properties b/quarkus/addons/flyway/runtime/src/main/resources/application.properties new file mode 100644 index 00000000000..9062673824c --- /dev/null +++ b/quarkus/addons/flyway/runtime/src/main/resources/application.properties @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +%dev,test.kie.flyway.enabled=true \ No newline at end of file diff --git a/quarkus/addons/persistence/jdbc/deployment/pom.xml b/quarkus/addons/persistence/jdbc/deployment/pom.xml index 53344acf127..c5defc7336b 100644 --- a/quarkus/addons/persistence/jdbc/deployment/pom.xml +++ b/quarkus/addons/persistence/jdbc/deployment/pom.xml @@ -44,12 +44,12 @@ kogito-addons-quarkus-common-deployment - io.quarkus - quarkus-arc-deployment + org.kie + kie-addons-quarkus-flyway-deployment io.quarkus - quarkus-flyway-deployment + quarkus-arc-deployment diff --git a/quarkus/addons/persistence/jdbc/runtime/pom.xml b/quarkus/addons/persistence/jdbc/runtime/pom.xml index 8b2083cc70b..aca45b3bda5 100644 --- a/quarkus/addons/persistence/jdbc/runtime/pom.xml +++ b/quarkus/addons/persistence/jdbc/runtime/pom.xml @@ -51,8 +51,8 @@ kie-addons-persistence-jdbc - io.quarkus - quarkus-flyway + org.kie + kie-addons-quarkus-flyway org.junit.jupiter diff --git a/quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactory.java b/quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactory.java deleted file mode 100644 index 5f5493d351a..00000000000 --- a/quarkus/addons/persistence/jdbc/runtime/src/main/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.kie.kogito.persistence.quarkus; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.OptionalInt; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.microprofile.config.spi.ConfigSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.smallrye.config.ConfigSourceContext; -import io.smallrye.config.ConfigSourceFactory; -import io.smallrye.config.ConfigValue; - -import static org.kie.kogito.persistence.quarkus.KogitoAddOnPersistenceJDBCConfigSource.ORDINAL; - -public class KogitoAddOnPersistenceJDBCConfigSourceFactory implements ConfigSourceFactory { - private static final Logger LOGGER = LoggerFactory.getLogger(KogitoAddOnPersistenceJDBCConfigSourceFactory.class); - - static final String FLYWAY_LOCATIONS = "quarkus.flyway.locations"; - static final String DATASOURCE_DB_KIND = "quarkus.datasource.db-kind"; - private static final String LOCATION_PREFIX = "classpath:/db/"; - static final String POSTGRESQL = "postgresql"; - private static final String ANSI = "ansi"; - - @Override - public Iterable getConfigSources(ConfigSourceContext context) { - ConfigValue flywayLocationsConfigValue = context.getValue(FLYWAY_LOCATIONS); - return getConfigSourcesInternal(context.getValue(DATASOURCE_DB_KIND).getValue(), - flywayLocationsConfigValue.getValue(), flywayLocationsConfigValue.getConfigSourceOrdinal()); - } - - Iterable getConfigSourcesInternal(String databaseName, String flywayLocationsValue, int flywayLocationsConfigSourceOrdinal) { - Map configuration = new HashMap<>(); - if (databaseName != null) { - if (flywayLocationsValue == null || flywayLocationsConfigSourceOrdinal == Integer.MIN_VALUE) { - configuration.put(FLYWAY_LOCATIONS, LOCATION_PREFIX + getDBName(databaseName)); - } else { - Set locations = Arrays.stream(flywayLocationsValue.split(",")).collect(Collectors.toSet()); - locations.add(LOCATION_PREFIX + getDBName(databaseName)); - configuration.put(FLYWAY_LOCATIONS, String.join(",", locations)); - } - } else { - LOGGER.warn("Kogito Flyway must have the property \"quarkus.datasource.db-kind\" to be set to initialize process schema."); - } - return List.of(new KogitoAddOnPersistenceJDBCConfigSource(configuration)); - } - - @Override - public OptionalInt getPriority() { - return OptionalInt.of(ORDINAL); - } - - private String getDBName(final String dbKind) { - if (POSTGRESQL.equals(dbKind)) { - return POSTGRESQL; - } else { - return ANSI; - } - } -} diff --git a/quarkus/addons/persistence/jdbc/runtime/src/test/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactoryTest.java b/quarkus/addons/persistence/jdbc/runtime/src/test/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactoryTest.java deleted file mode 100644 index c6033f3123e..00000000000 --- a/quarkus/addons/persistence/jdbc/runtime/src/test/java/org/kie/kogito/persistence/quarkus/KogitoAddOnPersistenceJDBCConfigSourceFactoryTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.kie.kogito.persistence.quarkus; - -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.microprofile.config.spi.ConfigSource; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.kie.kogito.persistence.quarkus.KogitoAddOnPersistenceJDBCConfigSourceFactory.FLYWAY_LOCATIONS; -import static org.kie.kogito.persistence.quarkus.KogitoAddOnPersistenceJDBCConfigSourceFactory.POSTGRESQL; - -class KogitoAddOnPersistenceJDBCConfigSourceFactoryTest { - - private final static KogitoAddOnPersistenceJDBCConfigSourceFactory factory = new KogitoAddOnPersistenceJDBCConfigSourceFactory(); - - @Test - void getConfigSourcesInternalExistingLocations() { - Set locationsSet = getLocationsSet(getConfigSource(POSTGRESQL, "/path/to/locations", Integer.MAX_VALUE) - .getValue(FLYWAY_LOCATIONS)); - - assertThat(locationsSet).containsExactlyInAnyOrder("/path/to/locations", "classpath:/db/postgresql"); - } - - @Test - void getConfigSourcesInternalDefaultLocations() { - Set locationsSet = getLocationsSet(getConfigSource(POSTGRESQL, "/path/to/locations", Integer.MIN_VALUE) - .getValue(FLYWAY_LOCATIONS)); - - assertThat(locationsSet).containsOnly("classpath:/db/postgresql"); - } - - @Test - void getConfigSourcesInternalNoExistingLocations() { - Set locationsSet = getLocationsSet(getConfigSource(POSTGRESQL, null, Integer.MAX_VALUE) - .getValue(FLYWAY_LOCATIONS)); - - assertThat(locationsSet).containsExactlyInAnyOrder("classpath:/db/postgresql"); - } - - @Test - void getConfigSourcesInternalDatabaseNameEmpty() { - ConfigSource configSource = getConfigSource(null, "/path/to/locations", Integer.MAX_VALUE); - assertThat(configSource.getPropertyNames()).isEmpty(); - } - - @Test - void getConfigSourcesInternalEnsuresNoDuplication() { - Set locationsSet = getLocationsSet(getConfigSource(POSTGRESQL, "classpath:/db/postgresql", Integer.MAX_VALUE) - .getValue(FLYWAY_LOCATIONS)); - - assertThat(locationsSet).containsExactlyInAnyOrder("classpath:/db/postgresql"); - } - - private static ConfigSource getConfigSource(String databaseName, String flywayLocationsValue, - int flywayLocationsConfigSourceOrdinal) { - Iterable configSources = factory.getConfigSourcesInternal(databaseName, flywayLocationsValue, - flywayLocationsConfigSourceOrdinal); - assertThat(configSources).hasSize(1); - return configSources.iterator().next(); - } - - private static Set getLocationsSet(String locations) { - return Arrays.stream(locations.split(",")).collect(Collectors.toSet()); - } -} \ No newline at end of file diff --git a/quarkus/addons/persistence/postgresql/deployment/pom.xml b/quarkus/addons/persistence/postgresql/deployment/pom.xml index 2b668718c1d..785f84a0285 100644 --- a/quarkus/addons/persistence/postgresql/deployment/pom.xml +++ b/quarkus/addons/persistence/postgresql/deployment/pom.xml @@ -44,16 +44,16 @@ kogito-addons-quarkus-common-deployment - io.quarkus - quarkus-arc-deployment + org.kie + kie-addons-quarkus-flyway-deployment io.quarkus - quarkus-reactive-pg-client-deployment + quarkus-arc-deployment io.quarkus - quarkus-flyway-deployment + quarkus-reactive-pg-client-deployment io.quarkus diff --git a/quarkus/addons/persistence/postgresql/runtime/pom.xml b/quarkus/addons/persistence/postgresql/runtime/pom.xml index 584cc425df1..a2f11150fb3 100644 --- a/quarkus/addons/persistence/postgresql/runtime/pom.xml +++ b/quarkus/addons/persistence/postgresql/runtime/pom.xml @@ -55,8 +55,8 @@ - io.quarkus - quarkus-flyway + org.kie + kie-addons-quarkus-flyway io.quarkus diff --git a/quarkus/addons/pom.xml b/quarkus/addons/pom.xml index 6b27efb5010..2a51d08ca82 100644 --- a/quarkus/addons/pom.xml +++ b/quarkus/addons/pom.xml @@ -40,6 +40,7 @@ messaging common rest-exception-handler + flyway persistence process-management source-files diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties index 977b9583315..4148d965723 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/application.properties @@ -23,8 +23,7 @@ quarkus.swagger-ui.always-include=true kogito.persistence.type=jdbc kogito.persistence.proto.marshaller=false quarkus.datasource.db-kind=postgresql -quarkus.flyway.migrate-at-start=true -quarkus.flyway.clean-at-start=true +kie.flyway.enabled=true quarkus.http.test-port=0 quarkus.log.level=INFO diff --git a/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-jdbc/src/main/resources/application.properties b/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-jdbc/src/main/resources/application.properties index d8f85971189..19109e37cdc 100644 --- a/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-jdbc/src/main/resources/application.properties +++ b/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-jdbc/src/main/resources/application.properties @@ -20,5 +20,5 @@ kogito.persistence.type=jdbc #run create tables scripts quarkus.datasource.db-kind=postgresql -quarkus.flyway.migrate-at-start=true -quarkus.flyway.clean-at-start=true \ No newline at end of file + +kie.flyway.enabled=true \ No newline at end of file diff --git a/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-postgresql/src/main/resources/application.properties b/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-postgresql/src/main/resources/application.properties index 91a52baeab1..e090cfc7beb 100644 --- a/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-postgresql/src/main/resources/application.properties +++ b/quarkus/integration-tests/integration-tests-quarkus-processes-persistence/integration-tests-quarkus-processes-postgresql/src/main/resources/application.properties @@ -19,6 +19,4 @@ kogito.persistence.type=postgresql -# Quarkus -quarkus.flyway.migrate-at-start=true -quarkus.flyway.clean-at-start=true \ No newline at end of file +kie.flyway.enabled=true \ No newline at end of file diff --git a/springboot/addons/flyway/pom.xml b/springboot/addons/flyway/pom.xml new file mode 100644 index 00000000000..00d429c9d30 --- /dev/null +++ b/springboot/addons/flyway/pom.xml @@ -0,0 +1,73 @@ + + + + + kogito-addons-springboot-parent + org.kie + 999-SNAPSHOT + + 4.0.0 + + kie-addons-springboot-flyway + Kie :: Add-Ons :: Spring Boot :: Flyway + + + org.kie.springboot.flyway + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.kie + kie-addons-flyway + + + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + org.mockito + mockito-junit-jupiter + test + + + ch.qos.logback + logback-classic + test + + + \ No newline at end of file diff --git a/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootAutoConfiguration.java b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootAutoConfiguration.java new file mode 100644 index 00000000000..dba3430b917 --- /dev/null +++ b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.springboot; + +import javax.sql.DataSource; + +import org.flywaydb.core.Flyway; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +@AutoConfiguration(after = { DataSourceAutoConfiguration.class }) +@ConditionalOnProperty(prefix = "kie.flyway", name = "enabled", havingValue = "true") +@ConditionalOnClass(Flyway.class) +@Import(DatabaseInitializationDependencyConfigurer.class) +@EnableConfigurationProperties(KieFlywaySpringbootProperties.class) +public class KieFlywaySpringbootAutoConfiguration { + + @Bean + public KieFlywaySpringbootInitializer kieFlyway(KieFlywaySpringbootProperties properties, ObjectProvider dataSource) { + + DataSource ds = dataSource.getIfAvailable(); + + return new KieFlywaySpringbootInitializer(properties, ds); + } + +} diff --git a/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootInitializer.java b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootInitializer.java new file mode 100644 index 00000000000..dff89d58c2f --- /dev/null +++ b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootInitializer.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.springboot; + +import javax.sql.DataSource; + +import org.kie.flyway.integration.KieFlywayRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.Ordered; + +public class KieFlywaySpringbootInitializer implements InitializingBean, Ordered { + private static final Logger LOGGER = LoggerFactory.getLogger(KieFlywaySpringbootInitializer.class); + + private final KieFlywaySpringbootProperties properties; + private final DataSource dataSource; + + public KieFlywaySpringbootInitializer(KieFlywaySpringbootProperties properties, DataSource dataSource) { + this.properties = properties; + this.dataSource = dataSource; + } + + @Override + public void afterPropertiesSet() { + KieFlywayRunner.get(properties) + .runFlyway(dataSource); + } + + @Override + public int getOrder() { + return 0; + } +} diff --git a/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootProperties.java b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootProperties.java new file mode 100644 index 00000000000..3c89ad447d6 --- /dev/null +++ b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/KieFlywaySpringbootProperties.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.springboot; + +import java.util.HashMap; +import java.util.Map; + +import org.kie.flyway.integration.KieFlywayConfiguration; +import org.kie.flyway.integration.KieFlywayNamedModule; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "kie.flyway") +public class KieFlywaySpringbootProperties implements KieFlywayConfiguration { + private boolean enabled = true; + + private Map modules = new HashMap<>(); + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Map getModules() { + return modules; + } + + public void setModules(Map modules) { + this.modules = modules; + } + + public static class KieFlywaySpringbootNamedModule implements KieFlywayNamedModule { + + private boolean enabled = true; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + } +} diff --git a/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/detector/KieFlywaySpringbootInitializerDetector.java b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/detector/KieFlywaySpringbootInitializerDetector.java new file mode 100644 index 00000000000..193f61d3ec9 --- /dev/null +++ b/springboot/addons/flyway/src/main/java/org/kie/flyway/springboot/detector/KieFlywaySpringbootInitializerDetector.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.flyway.springboot.detector; + +import java.util.Set; + +import org.kie.flyway.springboot.KieFlywaySpringbootInitializer; +import org.springframework.boot.sql.init.dependency.AbstractBeansOfTypeDatabaseInitializerDetector; +import org.springframework.core.Ordered; + +public class KieFlywaySpringbootInitializerDetector extends AbstractBeansOfTypeDatabaseInitializerDetector { + @Override + protected Set> getDatabaseInitializerBeanTypes() { + return Set.of(KieFlywaySpringbootInitializer.class); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } +} diff --git a/springboot/addons/flyway/src/main/resources/META-INF/beans.xml b/springboot/addons/flyway/src/main/resources/META-INF/beans.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/springboot/addons/flyway/src/main/resources/META-INF/spring.factories b/springboot/addons/flyway/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000000..84b09ca03ff --- /dev/null +++ b/springboot/addons/flyway/src/main/resources/META-INF/spring.factories @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# DataSource Initializer Detectors +org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ +org.kie.flyway.springboot.detector.KieFlywaySpringbootInitializerDetector \ No newline at end of file diff --git a/springboot/addons/flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/springboot/addons/flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000000..24653073af0 --- /dev/null +++ b/springboot/addons/flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +org.kie.flyway.springboot.KieFlywaySpringbootAutoConfiguration \ No newline at end of file diff --git a/springboot/addons/persistence/jdbc/pom.xml b/springboot/addons/persistence/jdbc/pom.xml index 12fe4766a38..5c523421399 100644 --- a/springboot/addons/persistence/jdbc/pom.xml +++ b/springboot/addons/persistence/jdbc/pom.xml @@ -42,6 +42,10 @@ org.kie kie-addons-persistence-jdbc + + org.kie + kie-addons-springboot-flyway + org.springframework.boot spring-boot-starter-web diff --git a/springboot/addons/persistence/postgresql/pom.xml b/springboot/addons/persistence/postgresql/pom.xml index 025fd3e8088..827ee103203 100644 --- a/springboot/addons/persistence/postgresql/pom.xml +++ b/springboot/addons/persistence/postgresql/pom.xml @@ -42,6 +42,10 @@ org.kie kie-addons-persistence-postgresql + + org.kie + kie-addons-springboot-flyway + org.springframework.boot spring-boot-starter-web diff --git a/springboot/addons/pom.xml b/springboot/addons/pom.xml index 46fd6ecde80..d6221ca7a6b 100644 --- a/springboot/addons/pom.xml +++ b/springboot/addons/pom.xml @@ -49,6 +49,7 @@ process-management task-management kubernetes + flyway persistence diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/src/main/resources/application.properties b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/src/main/resources/application.properties index 2b28c3283b9..580f609a9e0 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/src/main/resources/application.properties +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-jdbc/src/main/resources/application.properties @@ -21,5 +21,6 @@ server.address=0.0.0.0 kogito.persistence.type=jdbc -spring.flyway.locations=classpath:db/{vendor} -spring.flyway.enabled=true +kie.flyway.enabled=true + +spring.flyway.enabled=false diff --git a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/main/resources/application.properties b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/main/resources/application.properties index 8081c3c1aa3..ec75b6f6445 100644 --- a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/main/resources/application.properties +++ b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/main/resources/application.properties @@ -20,6 +20,8 @@ server.address=0.0.0.0 kogito.persistence.type=postgresql +kie.flyway.enabled=true +spring.flyway.enabled=false # Details https://www.postgresql.org/docs/9.6/static/libpq-connect.html#LIBPQ-CONNSTRING kogito.persistence.postgresql.connection.uri=postgresql://kogito-user:kogito-pass@localhost:5432/kogito \ No newline at end of file diff --git a/springboot/test/src/main/java/org/kie/kogito/testcontainers/springboot/PostgreSqlSpringBootTestResource.java b/springboot/test/src/main/java/org/kie/kogito/testcontainers/springboot/PostgreSqlSpringBootTestResource.java index eddd29e5f78..b9f32af757e 100644 --- a/springboot/test/src/main/java/org/kie/kogito/testcontainers/springboot/PostgreSqlSpringBootTestResource.java +++ b/springboot/test/src/main/java/org/kie/kogito/testcontainers/springboot/PostgreSqlSpringBootTestResource.java @@ -34,9 +34,6 @@ public class PostgreSqlSpringBootTestResource extends ConditionalSpringBootTestR public static final String SPRING_DATASOURCE_URL = "spring.datasource.url"; public static final String SPRING_DATASOURCE_USERNAME = "spring.datasource.username"; public static final String SPRING_DATASOURCE_PASSWORD = "spring.datasource.password"; - public static final String SPRING_FLYWAY_URL = "spring.flyway.url"; - public static final String SPRING_FLYWAY_USERNAME = "spring.flyway.user"; - public static final String SPRING_FLYWAY_PASSWORD = "spring.flyway.password"; public PostgreSqlSpringBootTestResource() { super(new KogitoPostgreSqlContainer()); @@ -49,9 +46,6 @@ protected Map getProperties() { properties.put(SPRING_DATASOURCE_URL, getTestResource().getJdbcUrl()); properties.put(SPRING_DATASOURCE_USERNAME, getTestResource().getUsername()); properties.put(SPRING_DATASOURCE_PASSWORD, getTestResource().getPassword()); - properties.put(SPRING_FLYWAY_URL, getTestResource().getJdbcUrl()); - properties.put(SPRING_FLYWAY_USERNAME, getTestResource().getUsername()); - properties.put(SPRING_FLYWAY_PASSWORD, getTestResource().getPassword()); return properties; } From 3d9eea40e2c91c4038de16feaa8f38debc36ce8f Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti <65240126+fjtirado@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:53:00 +0200 Subject: [PATCH 12/15] [Fix #3674] Signalling compensation when abortion (#3683) --- .../instance/impl/ProcessInstanceImpl.java | 9 +++ .../java/org/jbpm/ruleflow/core/Metadata.java | 1 + .../parser/ServerlessWorkflowParser.java | 1 + .../src/main/resources/compensation.sw.json | 4 +- .../resources/compensation_aborted.sw.json | 59 +++++++++++++++++++ .../quarkus/workflows/CompensationRestIT.java | 20 ++++++- 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation_aborted.sw.json diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java index 98ea0bbee86..b685860357e 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java @@ -27,11 +27,13 @@ import org.drools.core.common.InternalKnowledgeRuntime; import org.jbpm.process.core.Context; import org.jbpm.process.core.ContextContainer; +import org.jbpm.process.core.context.exception.CompensationScope; import org.jbpm.process.core.impl.XmlProcessDumper; import org.jbpm.process.core.impl.XmlProcessDumperFactory; import org.jbpm.process.instance.ContextInstance; import org.jbpm.process.instance.InternalProcessRuntime; import org.jbpm.process.instance.ProcessInstance; +import org.jbpm.ruleflow.core.Metadata; import org.jbpm.workflow.core.WorkflowProcess; import org.kie.api.definition.process.Process; import org.kie.api.runtime.rule.Agenda; @@ -152,9 +154,16 @@ public void setState(final int state, String outcome) { } public void internalSetState(final int state) { + if (state == KogitoProcessInstance.STATE_ABORTED && automaticCompensation()) { + signalEvent(Metadata.COMPENSATION, CompensationScope.IMPLICIT_COMPENSATION_PREFIX + process.getId()); + } this.state = state; } + private boolean automaticCompensation() { + return process.getMetaData().containsKey(Metadata.COMPENSATE_WHEN_ABORTED); + } + @Override public int getState() { return this.state; diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/Metadata.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/Metadata.java index 6bca5445bf4..b552fd128b6 100644 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/Metadata.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/Metadata.java @@ -62,6 +62,7 @@ public class Metadata { public static final String LINK_NAME = "LinkName"; public static final String CONDITION = "Condition"; public static final String IS_FOR_COMPENSATION = "isForCompensation"; + public static final String COMPENSATE_WHEN_ABORTED = "compensateIfAborted"; public static final String CORRELATION_KEY = "CorrelationKey"; public static final String CUSTOM_ASYNC = "customAsync"; public static final String CUSTOM_AUTO_START = "customAutoStart"; diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/ServerlessWorkflowParser.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/ServerlessWorkflowParser.java index b7ef57251f9..8fd92f82f35 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/ServerlessWorkflowParser.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/ServerlessWorkflowParser.java @@ -147,6 +147,7 @@ private GeneratedInfo parseProcess() { handlers.forEach(StateHandler::handleConnections); if (parserContext.isCompensation()) { factory.metaData(Metadata.COMPENSATION, true); + factory.metaData(Metadata.COMPENSATE_WHEN_ABORTED, true); factory.addCompensationContext(workflow.getId()); } TimeoutsDefinition timeouts = workflow.getTimeouts(); diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation.sw.json b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation.sw.json index 884b5fc16da..8c35b7c4fc6 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation.sw.json +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation.sw.json @@ -1,8 +1,8 @@ { "id": "compensation", "version": "1.0", - "name": "Workflow Error example", - "description": "An example of how compensation works", + "name": "Workflow compensation", + "description": "Test compensation works", "start": "printStatus", "errors": [ { diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation_aborted.sw.json b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation_aborted.sw.json new file mode 100644 index 00000000000..363513baf88 --- /dev/null +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/main/resources/compensation_aborted.sw.json @@ -0,0 +1,59 @@ +{ + "id": "automatic_compensation", + "version": "1.0", + "name": "Workflow abortion compensation", + "description": "Testing automatic compensation on abort", + "start": "double", + "functions": [ + { + "name": "double", + "type": "expression", + "operation": ".value*=2" + }, + { + "name": "half", + "type": "expression", + "operation": ".value/=2" + }], + "events": [ + { + "name": "never", + "source": "", + "type": "never" + } + ], + "states": [ + { + "name": "double", + "type": "operation", + "compensatedBy" : "half", + "actions" : [{ + "functionRef" : "double" + }], + "transition": "waitEvent" + }, + { + "name": "waitEvent", + "type": "event", + "onEvents": [ + { + "eventRefs": [ + "never" + ], + "actions": [ + ] + } + ], + "end" : true + }, + { + "name": "half", + "usedForCompensation" : true, + "type": "operation", + "actions" : [{ + "functionRef" : "half" + }], + "end": true + } + ] +} diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java index 596f8e14b68..e6af51a69cf 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-integration-test/src/test/java/org/kie/kogito/quarkus/workflows/CompensationRestIT.java @@ -52,7 +52,6 @@ public void testErrorRest2() { .statusCode(201) .body("workflowdata.compensated", is(true)) .body("workflowdata.isEven", is(false)); - } @Test @@ -66,4 +65,23 @@ public void testErrorRest3() { .statusCode(201) .body("workflowdata.compensated", is(false)); } + + @Test + public void testCompensationOnAbort() { + String pid = given() + .contentType(ContentType.JSON) + .accept(ContentType.JSON) + .body("{\"value\" : 2}").when() + .post("/automatic_compensation") + .then() + .statusCode(201).extract().path("id"); + given() + .contentType(ContentType.JSON) + .accept(ContentType.JSON) + .when() + .delete("/automatic_compensation/" + pid) + .then() + .statusCode(200) + .body("workflowdata.value", is(2)); + } } From e5a4278a4cc47ccb13f7f1f661d07b9e1bdc2670 Mon Sep 17 00:00:00 2001 From: Gabriele Cardosi Date: Wed, 2 Oct 2024 17:15:03 +0200 Subject: [PATCH 13/15] [incubator-kie-issues#1500] Add javadoc to kogito properties (#3685) * [incubator-kie-issues#1500] Add javadoc to kogito properties * [incubator-kie-issues#1450] Include CI hack inside kie-addons-quarkus-process-dynamic-integration-tests pom to avoid io.quarkus.bootstrap.BootstrapException: Failed to create the application model for org.kie:kie-addons-quarkus-process-dynamic-integration-tests::jar:999-SNAPSHOT error --------- Co-authored-by: Gabriele-Cardosi --- .../org/kie/kogito/codegen/api/Generator.java | 3 ++ .../kogito/codegen/core/GeneratorConfig.java | 3 ++ .../codegen/decision/DecisionCodegen.java | 29 +++++++++++++++++++ .../persistence/PersistenceGenerator.java | 9 ++++++ .../rules/config/NamedRuleUnitConfig.java | 9 ++++++ .../WorkflowOperationIdFactoryProvider.java | 8 +++++ .../addons/dynamic/integration-tests/pom.xml | 14 +++++++++ .../quarkus/workflow/KogitoBeanProducer.java | 5 ++++ 8 files changed, 80 insertions(+) diff --git a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/Generator.java b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/Generator.java index fdb95496a78..ac62d781179 100644 --- a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/Generator.java +++ b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/Generator.java @@ -33,6 +33,9 @@ public interface Generator { GeneratedFileType REST_TYPE = GeneratedFileType.of("REST", GeneratedFileType.Category.SOURCE, true, true); GeneratedFileType MODEL_TYPE = GeneratedFileType.of("MODEL", GeneratedFileType.Category.SOURCE, true, true); + /** + * kogito.codegen.(engine_name) -> (boolean) enable/disable engine code generation (default true) + */ String CONFIG_PREFIX = "kogito.codegen."; /** diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/GeneratorConfig.java b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/GeneratorConfig.java index 6886ccc49f1..31f813356f8 100644 --- a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/GeneratorConfig.java +++ b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/GeneratorConfig.java @@ -23,6 +23,9 @@ */ public class GeneratorConfig { + /** + * the type of generated rest (currently used only by processes); possible values: reactive; (default is empty) + */ public static final String KOGITO_REST_RESOURCE_TYPE_PROP = "kogito.rest.resource.type"; private GeneratorConfig() { diff --git a/kogito-codegen-modules/kogito-codegen-decisions/src/main/java/org/kie/kogito/codegen/decision/DecisionCodegen.java b/kogito-codegen-modules/kogito-codegen-decisions/src/main/java/org/kie/kogito/codegen/decision/DecisionCodegen.java index b0944b54099..757bd5caf04 100644 --- a/kogito-codegen-modules/kogito-codegen-decisions/src/main/java/org/kie/kogito/codegen/decision/DecisionCodegen.java +++ b/kogito-codegen-modules/kogito-codegen-decisions/src/main/java/org/kie/kogito/codegen/decision/DecisionCodegen.java @@ -72,9 +72,38 @@ public class DecisionCodegen extends AbstractGenerator { public static final Logger LOGGER = LoggerFactory.getLogger(DecisionCodegen.class); public static final String GENERATOR_NAME = "decisions"; + /** + * (boolean) generate java classes to support strongly typed input (default false) + */ public static String STRONGLY_TYPED_CONFIGURATION_KEY = "kogito.decisions.stronglytyped"; + /** + * model validation strategy; possible values: ENABLED, DISABLED, IGNORE; (default ENABLED) + */ public static String VALIDATION_CONFIGURATION_KEY = "kogito.decisions.validation"; + /** + * (string) kafka bootstrap server address + */ + public static final String KOGITO_ADDON_TRACING_DECISION_KAFKA_BOOTSTRAPADDRESS = "kogito.addon.tracing.decision.kafka.bootstrapAddress"; + /** + * (string) name of the decision topic; default to kogito-tracing-decision + */ + public static final String KOGITO_ADDON_TRACING_DECISION_KAFKA_TOPIC_NAME = "kogito.addon.tracing.decision.kafka.topic.name"; + /** + * (integer) number of decision topic partitions; default to 1 + */ + public static final String KOGITO_ADDON_TRACING_DECISION_KAFKA_TOPIC_PARTITIONS = "kogito.addon.tracing.decision.kafka.topic.partitions"; + + /** + * (integer) number of decision topic replication factor; default to 1 + */ + public static final String KOGITO_ADDON_TRACING_DECISION_KAFKA_TOPIC_REPLICATION_FACTOR = "kogito.addon.tracing.decision.kafka.topic.replicationFactor"; + + /** + * (boolean) enable/disable asynchronous collection of decision events; default to true + */ + public static final String KOGITO_ADDON_TRACING_DECISION_ASYNC_ENABLED = "kogito.addon.tracing.decision.asyncEnabled"; + public static DecisionCodegen ofCollectedResources(KogitoBuildContext context, Collection resources) { OASFactoryResolver.instance(); // manually invoke SPI, o/w Kogito CodeGen Kogito Quarkus extension failure at NewFileHotReloadTest due to java.util.ServiceConfigurationError: org.eclipse.microprofile.openapi.spi.OASFactoryResolver: io.smallrye.openapi.spi.OASFactoryResolverImpl not a subtype List dmnResources = resources.stream() diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java index 55f40fcf6ba..7a469697202 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java @@ -77,10 +77,19 @@ public class PersistenceGenerator extends AbstractGenerator { * Kogito persistence properties */ // Generic + /** + * (boolean) enable/disable proto generation for DATA-INDEX; default to true + */ public static final String KOGITO_PERSISTENCE_DATA_INDEX_PROTO_GENERATION = "kogito.persistence.data-index.proto.generation"; public static final String KOGITO_PERSISTENCE_DATA_INDEX_PROTO_GENERATION_DEFAULT = "true"; + /** + * (boolean) enable/disable proto marshaller generation; default to true + */ public static final String KOGITO_PERSISTENCE_PROTO_MARSHALLER = "kogito.persistence.proto.marshaller"; public static final String KOGITO_PERSISTENCE_PROTO_MARSHALLER_DEFAULT = "true"; + /** + * (string) kind of persistence used; possible values: filesystem, infinispan, mongodb, postgresql, kafka, jdbc; default to infinispan + */ public static final String KOGITO_PERSISTENCE_TYPE = "kogito.persistence.type"; /** diff --git a/kogito-codegen-modules/kogito-codegen-rules/src/main/java/org/kie/kogito/codegen/rules/config/NamedRuleUnitConfig.java b/kogito-codegen-modules/kogito-codegen-rules/src/main/java/org/kie/kogito/codegen/rules/config/NamedRuleUnitConfig.java index d655bf1838f..f0d08519170 100644 --- a/kogito-codegen-modules/kogito-codegen-rules/src/main/java/org/kie/kogito/codegen/rules/config/NamedRuleUnitConfig.java +++ b/kogito-codegen-modules/kogito-codegen-rules/src/main/java/org/kie/kogito/codegen/rules/config/NamedRuleUnitConfig.java @@ -31,8 +31,17 @@ public final class NamedRuleUnitConfig { private static String CONFIG_PREFIX = "kogito.rules."; + /** + * (string) kind of event processing type for a given rule-unit; possible values: CLOUD, STREAM; default is null + */ private static String CONFIG_EVENT_PROCESSING_TYPE = CONFIG_PREFIX + "\"%s\".event-processing-type"; + /** + * (string) kind of event clock type for a given rule-unit; possible values: PSEUDO, REALTIME; default is null + */ private static String CONFIG_CLOCK_TYPE = CONFIG_PREFIX + "\"%s\".clock-type"; + /** + * (integer) size of session poolfor a given rule-unit; possible values; default is null + */ private static String CONFIG_SESSIONS_POOL = CONFIG_PREFIX + "\"%s\".sessions-pool"; public static List fromContext(KogitoBuildContext context) { diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/operationid/WorkflowOperationIdFactoryProvider.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/operationid/WorkflowOperationIdFactoryProvider.java index af53cc1a0ab..ec176854479 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/operationid/WorkflowOperationIdFactoryProvider.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/operationid/WorkflowOperationIdFactoryProvider.java @@ -25,6 +25,14 @@ public class WorkflowOperationIdFactoryProvider { + /** + * (string) strategy for generating the configuration key of open API specifications; possible values are: + * file_name: uses the last element of the spec uri + * full_uri: uses the full path of the uri + * spec_title: uses the spec title + * function_name: uses the function name + * + */ public static final String PROPERTY_NAME = "kogito.sw.operationIdStrategy"; private static final Map operationIds = new HashMap<>(); diff --git a/quarkus/addons/dynamic/integration-tests/pom.xml b/quarkus/addons/dynamic/integration-tests/pom.xml index 4fe89ac8159..7109502889e 100644 --- a/quarkus/addons/dynamic/integration-tests/pom.xml +++ b/quarkus/addons/dynamic/integration-tests/pom.xml @@ -41,6 +41,20 @@ rest-assured test + + + org.apache.kie.sonataflow + sonataflow-quarkus-deployment + ${project.version} + pom + test + + + * + * + + + diff --git a/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java b/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java index ea7fe04f789..7b282dc8f93 100644 --- a/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java +++ b/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/src/main/java/org/kie/kogito/quarkus/workflow/KogitoBeanProducer.java @@ -42,6 +42,11 @@ @ApplicationScoped public class KogitoBeanProducer { + /** + * (string) strategy to resolve a Process version to use; possible values: project, workflow; if "project", requires project GAV; default is workflow + */ + public static final String KOGITO_WORKFLOW_VERSION_STRATEGY = "kogito.workflow.version-strategy"; + @DefaultBean @Produces CorrelationService correlationService() { From f2ca75386be154629c1ad1028a33be94ab7b5b69 Mon Sep 17 00:00:00 2001 From: Roberto Oliveira Date: Thu, 3 Oct 2024 09:07:37 -0400 Subject: [PATCH 14/15] [incubator-kie-issues#1504] Conditionally build all or only reproducible modules based on only.reproducible flag - only for release build (#3687) Co-authored-by: Gabriele-Cardosi # Conflicts: # .ci/jenkins/Jenkinsfile.deploy --- jbpm/pom.xml | 62 ++++++++++++++++++++++++++++++++++------------ springboot/pom.xml | 42 +++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/jbpm/pom.xml b/jbpm/pom.xml index 9f31c94d8a8..b5638d6be7b 100755 --- a/jbpm/pom.xml +++ b/jbpm/pom.xml @@ -20,26 +20,34 @@ --> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - 4.0.0 + 4.0.0 - - org.kie.kogito - kogito-build-parent - 999-SNAPSHOT - ../kogito-build/kogito-build-parent/pom.xml + + org.kie.kogito + kogito-build-parent + 999-SNAPSHOT + ../kogito-build/kogito-build-parent/pom.xml - + - jbpm - pom - Kogito :: jBPM - jBPM: a Business Process Management - http://www.jbpm.org + jbpm + pom + Kogito :: jBPM + jBPM: a Business Process Management + http://www.jbpm.org - + + + allSubmodules + + + !only.reproducible + + + jbpm-flow jbpm-flow-builder jbpm-bpmn2 @@ -50,6 +58,28 @@ jbpm-tools jbpm-tests jbpm-deps-groups - + + + + + onlyReproducible + + + only.reproducible + + + + jbpm-flow + jbpm-flow-builder + jbpm-bpmn2 + jbpm-flow-migration + process-serialization-protobuf + process-workitems + jbpm-usertask + jbpm-tools + jbpm-deps-groups + + + diff --git a/springboot/pom.xml b/springboot/pom.xml index 84d9abd27dc..0e7a0f42316 100644 --- a/springboot/pom.xml +++ b/springboot/pom.xml @@ -34,13 +34,39 @@ Kogito :: Spring Boot pom - - bom - addons - starters - archetype - test - integration-tests - + + + allSubmodules + + + !only.reproducible + + + + bom + addons + starters + archetype + test + integration-tests + + + + + onlyReproducible + + + only.reproducible + + + + bom + addons + starters + archetype + test + + + \ No newline at end of file From 3e8a0cc2e98b2f013f95fbd11569b0ef72975eb2 Mon Sep 17 00:00:00 2001 From: Gabriele Cardosi Date: Thu, 3 Oct 2024 12:04:33 +0200 Subject: [PATCH 15/15] [incubator-kie-issues#1473] Introduce Transactional annotation, conditionally deleted (#3671) * [incubator-kie-issues#1473] WIP - Implemented transactional imports and annotations with optional removal. Add unit tests. Small refactoring to allow unit testing/ TDD * [incubator-kie-issues#1473] Simplified following suggestions. Now the annotation is conditionally add during code generation. * [incubator-kie-issues#1473] Implemented KogitoContextTestUtils#restContextBuilders for rest-specific tests. Enforced exclusion of "Java" context from processes' rest generation. * [incubator-kie-issues#1473] Set log level to debug inside manageTransactional * [incubator-kie-issues#1473] Add spring-tx dependency to jbpm-spring-boot-starter to be always available for springboot projects * [incubator-kie-issues#1473] Add quarkus-narayana-jta dependency to kogito-quarkus-workflow-common to be always available for quarkus projects * [incubator-kie-issues#1473] Add quarkus-narayana-jta-deployment dependency * [incubator-kie-issues#1473] Introduce nasty workaround (delay) to avoid ARJUNA issues with nested threads * [incubator-kie-issues#1473] Disabling transaction for sonataflow-quarkus-integration-test * [incubator-kie-issues#1473] Conditionally add the thread sleep. Fix kogito.processes.transactionEnabled variable * [incubator-kie-issues#1473] Importing new wait strategy. * [incubator-kie-issues#1473] WIP - Experimenting Thread.join inside transaction (instead of Thread.sleep) * [incubator-kie-issues#1473] WIP - fix formatting * [incubator-kie-issues#1473] WIP - commented out conditionally excluded serverless transaction. Disable transaction workaround. * [incubator-kie-issues#1473] WIP - commented out conditionally excluded serverless transaction. Disable transaction workaround. * [incubator-kie-issues#1473] Disabling transaction for serverless * [incubator-kie-issues#1473] Fix formatting * [incubator-kie-issues#1473] Fix test * [incubator-kie-issues#1473] Fixed as per PR suggestion. Using context.hasRest() instead of name.equals("Java") to check for rest endpoint creation. Implemented MockQuarkusKogitoBuildContext and MockSpringBootKogitoBuildContext to override the hasRest method during tests. --------- Co-authored-by: Gabriele-Cardosi --- .../impl/MockQuarkusKogitoBuildContext.java | 51 +++++ .../MockSpringBootKogitoBuildContext.java | 50 +++++ .../api/utils/KogitoContextTestUtils.java | 12 ++ .../codegen/process/ProcessCodegen.java | 21 +- .../process/ProcessResourceGenerator.java | 199 +++++++++++++----- .../RestResourceSpringTemplate.java | 3 +- .../process/ProcessResourceGeneratorTest.java | 116 ++++++++-- .../events/CodegenMessageStartEventTest.java | 4 +- .../process/events/CodegenUserTaskTest.java | 2 +- .../pom.xml | 4 + .../pom.xml | 4 + .../kogito-quarkus-workflow-common/pom.xml | 4 + .../pom.xml | 4 + 13 files changed, 397 insertions(+), 77 deletions(-) create mode 100644 kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockQuarkusKogitoBuildContext.java create mode 100644 kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockSpringBootKogitoBuildContext.java diff --git a/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockQuarkusKogitoBuildContext.java b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockQuarkusKogitoBuildContext.java new file mode 100644 index 00000000000..9972c2d7f0a --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockQuarkusKogitoBuildContext.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.codegen.api.context.impl; + +/** + * Mocked QuarkusKogitoBuildContext to provide hasRest() = true + * during test + */ +public class MockQuarkusKogitoBuildContext extends QuarkusKogitoBuildContext { + + protected MockQuarkusKogitoBuildContext(MockQuarkusKogitoBuildContextBuilder builder) { + super(builder); + } + + public static Builder builder() { + return new MockQuarkusKogitoBuildContextBuilder(); + } + + @Override + public boolean hasRest() { + return true; + } + + protected static class MockQuarkusKogitoBuildContextBuilder extends QuarkusKogitoBuildContextBuilder { + + protected MockQuarkusKogitoBuildContextBuilder() { + } + + @Override + public MockQuarkusKogitoBuildContext build() { + return new MockQuarkusKogitoBuildContext(this); + } + + } +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockSpringBootKogitoBuildContext.java b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockSpringBootKogitoBuildContext.java new file mode 100644 index 00000000000..32a865ebd1f --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/context/impl/MockSpringBootKogitoBuildContext.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.codegen.api.context.impl; + +/** + * Mocked SpringBootKogitoBuildContext to provide hasRest() = true + * during test + */ +public class MockSpringBootKogitoBuildContext extends SpringBootKogitoBuildContext { + + protected MockSpringBootKogitoBuildContext(MockSpringBootKogitoBuildContextBuilder builder) { + super(builder); + } + + public static Builder builder() { + return new MockSpringBootKogitoBuildContextBuilder(); + } + + @Override + public boolean hasRest() { + return true; + } + + protected static class MockSpringBootKogitoBuildContextBuilder extends SpringBootKogitoBuildContextBuilder { + + protected MockSpringBootKogitoBuildContextBuilder() { + } + + @Override + public MockSpringBootKogitoBuildContext build() { + return new MockSpringBootKogitoBuildContext(this); + } + } +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/utils/KogitoContextTestUtils.java b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/utils/KogitoContextTestUtils.java index e96c2c7a347..3c7a273ea18 100644 --- a/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/utils/KogitoContextTestUtils.java +++ b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/utils/KogitoContextTestUtils.java @@ -25,6 +25,8 @@ import org.junit.jupiter.params.provider.Arguments; import org.kie.kogito.codegen.api.context.KogitoBuildContext; import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext; +import org.kie.kogito.codegen.api.context.impl.MockQuarkusKogitoBuildContext; +import org.kie.kogito.codegen.api.context.impl.MockSpringBootKogitoBuildContext; import org.kie.kogito.codegen.api.context.impl.QuarkusKogitoBuildContext; import org.kie.kogito.codegen.api.context.impl.SpringBootKogitoBuildContext; @@ -44,6 +46,16 @@ public static Stream contextBuilders() { Arguments.of(SpringBootKogitoBuildContext.builder())); } + /** + * + * @return Mocked QuarkusKogitoBuildContext and SpringBootKogitoBuildContext providing hasRest() = true + */ + public static Stream restContextBuilders() { + return Stream.of( + Arguments.of(MockQuarkusKogitoBuildContext.builder()), + Arguments.of(MockSpringBootKogitoBuildContext.builder())); + } + public static Predicate mockClassAvailabilityResolver(Collection includedClasses, Collection excludedClasses) { return mockClassAvailabilityResolver(includedClasses, excludedClasses, KogitoContextTestUtils.class.getClassLoader()); } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java index 6f5ba05f7a5..c360ec5e8c2 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java @@ -76,6 +76,7 @@ import static java.lang.String.format; import static java.util.stream.Collectors.toList; +import static org.kie.kogito.codegen.process.ProcessResourceGenerator.TRANSACTION_ENABLED; import static org.kie.kogito.grafana.GrafanaConfigurationWriter.buildDashboardName; import static org.kie.kogito.grafana.GrafanaConfigurationWriter.generateOperationalDashboard; import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeClassName; @@ -352,20 +353,23 @@ protected Collection internalGenerate() { ProcessMetaData metaData = processIdToMetadata.get(workFlowProcess.getId()); - //Creating and adding the ResourceGenerator - ProcessResourceGenerator processResourceGenerator = new ProcessResourceGenerator( + //Creating and adding the ResourceGenerator for REST generation + if (context().hasRest()) { + ProcessResourceGenerator processResourceGenerator = new ProcessResourceGenerator( context(), workFlowProcess, modelClassGenerator.className(), execModelGen.className(), applicationCanonicalName()); - processResourceGenerator + processResourceGenerator .withUserTasks(processIdToUserTaskModel.get(workFlowProcess.getId())) .withSignals(metaData.getSignals()) - .withTriggers(metaData.isStartable(), metaData.isDynamic(), metaData.getTriggers()); + .withTriggers(metaData.isStartable(), metaData.isDynamic(), metaData.getTriggers()) + .withTransaction(isTransactionEnabled()); - rgs.add(processResourceGenerator); + rgs.add(processResourceGenerator); + } if (metaData.getTriggers() != null) { @@ -468,7 +472,7 @@ protected Collection internalGenerate() { svgs.keySet().stream().forEach(key -> storeFile(GeneratedFileType.INTERNAL_RESOURCE, "META-INF/processSVG/" + key + ".svg", svgs.get(key))); } - if (context().hasRESTForGenerator(this)) { + if (context().hasRest() && context().hasRESTForGenerator(this)) { final ProcessCloudEventMetaFactoryGenerator topicsGenerator = new ProcessCloudEventMetaFactoryGenerator(context(), processExecutableModelGenerators); storeFile(REST_TYPE, topicsGenerator.generatedFilePath(), topicsGenerator.generate()); @@ -504,6 +508,11 @@ protected Collection internalGenerate() { return generatedFiles; } + protected boolean isTransactionEnabled() { + String processTransactionProperty = String.format("kogito.%s.%s", GENERATOR_NAME, TRANSACTION_ENABLED); + return "true".equalsIgnoreCase(context().getApplicationProperty(processTransactionProperty).orElse("true")); + } + private void storeFile(GeneratedFileType type, String path, String source) { if (generatedFiles.stream().anyMatch(f -> path.equals(f.relativePath()))) { LOGGER.warn("There's already a generated file named {} to be compiled. Ignoring.", path); diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java index 90ab0277b06..165477103f0 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java @@ -29,6 +29,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import org.drools.codegen.common.di.DependencyInjectionAnnotator; +import org.drools.codegen.common.rest.RestAnnotator; import org.drools.util.StringUtils; import org.jbpm.compiler.canonical.ProcessToExecModelGenerator; import org.jbpm.compiler.canonical.TriggerMetaData; @@ -44,6 +46,8 @@ import org.kie.kogito.codegen.core.GeneratorConfig; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess; import org.kie.kogito.internal.utils.ConversionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Modifier.Keyword; @@ -73,6 +77,15 @@ */ public class ProcessResourceGenerator { + /** + * Flag used to configure transaction enablement. Default to true + */ + public static final String TRANSACTION_ENABLED = "transactionEnabled"; + + static final String INVALID_CONTEXT_TEMPLATE = "ProcessResourceGenerator can't be used for context without Rest %s"; + + private static final Logger LOG = LoggerFactory.getLogger(ProcessResourceGenerator.class); + private static final String REST_TEMPLATE_NAME = "RestResource"; private static final String REACTIVE_REST_TEMPLATE_NAME = "ReactiveRestResource"; private static final String REST_USER_TASK_TEMPLATE_NAME = "RestResourceUserTask"; @@ -93,6 +106,7 @@ public class ProcessResourceGenerator { private boolean startable; private boolean dynamic; + private boolean transactionEnabled; private List triggers; private List userTasks; @@ -106,6 +120,9 @@ public ProcessResourceGenerator( String modelfqcn, String processfqcn, String appCanonicalName) { + if (!context.hasRest()) { + throw new IllegalArgumentException(String.format(INVALID_CONTEXT_TEMPLATE, context.name())); + } this.context = context; this.process = process; this.processId = process.getId(); @@ -134,6 +151,11 @@ public ProcessResourceGenerator withTriggers(boolean startable, boolean dynamic, return this; } + public ProcessResourceGenerator withTransaction(boolean transactionEnabled) { + this.transactionEnabled = transactionEnabled; + return this; + } + public String getTaskModelFactory() { return taskModelFactoryUnit.toString(); } @@ -149,27 +171,104 @@ public String className() { protected String getRestTemplateName() { boolean isReactiveGenerator = "reactive".equals(context.getApplicationProperty(GeneratorConfig.KOGITO_REST_RESOURCE_TYPE_PROP) .orElse("")); - boolean isQuarkus = context.name().equals(QuarkusKogitoBuildContext.CONTEXT_NAME); + return isQuarkus() && isReactiveGenerator ? REACTIVE_REST_TEMPLATE_NAME : REST_TEMPLATE_NAME; + } - return isQuarkus && isReactiveGenerator ? REACTIVE_REST_TEMPLATE_NAME : REST_TEMPLATE_NAME; + protected boolean isQuarkus() { + return context.name().equals(QuarkusKogitoBuildContext.CONTEXT_NAME); } public String generate() { - TemplatedGenerator.Builder templateBuilder = TemplatedGenerator.builder() - .withFallbackContext(QuarkusKogitoBuildContext.CONTEXT_NAME); - CompilationUnit clazz = templateBuilder.build(context, getRestTemplateName()) - .compilationUnitOrThrow(); - clazz.setPackageDeclaration(process.getPackageName()); - clazz.addImport(modelfqcn); - clazz.addImport(modelfqcn + "Output"); - clazz.addImport(modelfqcn + "Input"); - ClassOrInterfaceDeclaration template = clazz + return getCompilationUnit().toString(); + } + + protected CompilationUnit getCompilationUnit() { + TemplatedGenerator.Builder templateBuilder = createTemplatedGeneratorBuilder(); + CompilationUnit toReturn = createCompilationUnit(templateBuilder); + addPackageAndImports(toReturn); + ClassOrInterfaceDeclaration template = toReturn .findFirst(ClassOrInterfaceDeclaration.class) .orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a class or interface declaration!")); template.setName(resourceClazzName); AtomicInteger index = new AtomicInteger(0); //Generate signals endpoints + generateSignalsEndpoints(templateBuilder, template, index); + + // security must be applied before user tasks are added to make sure that user task + // endpoints are not security annotated as they should restrict access based on user assignments + securityAnnotated(template); + + Map typeInterpolations = new HashMap<>(); + taskModelFactoryUnit = parse(this.getClass().getResourceAsStream("/class-templates/TaskModelFactoryTemplate" + + ".java")); + String taskModelFactorySimpleClassName = + sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + "TaskModelFactory"); + taskModelFactoryUnit.setPackageDeclaration(process.getPackageName()); + taskModelFactoryClassName = process.getPackageName() + "." + taskModelFactorySimpleClassName; + ClassOrInterfaceDeclaration taskModelFactoryClass = + taskModelFactoryUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(IllegalStateException::new); + taskModelFactoryClass.setName(taskModelFactorySimpleClassName); + typeInterpolations.put("$TaskModelFactory$", taskModelFactoryClassName); + + manageUserTasks(templateBuilder, template, taskModelFactoryClass, index); + + typeInterpolations.put("$Clazz$", resourceClazzName); + typeInterpolations.put("$Type$", dataClazzName); + template.findAll(StringLiteralExpr.class).forEach(this::interpolateStrings); + template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateTypes(cls, typeInterpolations)); + + TagResourceGenerator.addTags(toReturn, process, context); + + template.findAll(MethodDeclaration.class).forEach(this::interpolateMethods); + + if (context.hasDI()) { + template.findAll(FieldDeclaration.class, + CodegenUtils::isProcessField).forEach(fd -> context.getDependencyInjectionAnnotator().withNamedInjection(fd, processId)); + } else { + template.findAll(FieldDeclaration.class, + CodegenUtils::isProcessField).forEach(this::initializeProcessField); + } + + // if triggers are not empty remove createResource method as there is another trigger to start process instances + if ((!startable && !dynamic) || !isPublic()) { + Optional createResourceMethod = + template.findFirst(MethodDeclaration.class).filter(md -> md.getNameAsString().equals( + "createResource_" + processName)); + createResourceMethod.ifPresent(template::remove); + } + + if (context.hasDI()) { + context.getDependencyInjectionAnnotator().withApplicationComponent(template); + } + + enableValidation(template); + + manageTransactional(toReturn); + + template.getMembers().sort(new BodyDeclarationComparator()); + return toReturn; + } + + protected TemplatedGenerator.Builder createTemplatedGeneratorBuilder() { + return TemplatedGenerator.builder() + .withFallbackContext(QuarkusKogitoBuildContext.CONTEXT_NAME); + } + + protected CompilationUnit createCompilationUnit(TemplatedGenerator.Builder templateBuilder) { + return templateBuilder.build(context, getRestTemplateName()) + .compilationUnitOrThrow(); + } + + protected void addPackageAndImports(CompilationUnit compilationUnit) { + compilationUnit.setPackageDeclaration(process.getPackageName()); + compilationUnit.addImport(modelfqcn); + compilationUnit.addImport(modelfqcn + "Output"); + compilationUnit.addImport(modelfqcn + "Input"); + } + + protected void generateSignalsEndpoints(TemplatedGenerator.Builder templateBuilder, + ClassOrInterfaceDeclaration template, AtomicInteger index) { Optional.ofNullable(signals) .ifPresent(signalsMap -> { //using template class to the endpoints generation @@ -265,20 +364,10 @@ public String generate() { }); }); }); + } - // security must be applied before user tasks are added to make sure that user task - // endpoints are not security annotated as they should restrict access based on user assignments - securityAnnotated(template); - - Map typeInterpolations = new HashMap<>(); - taskModelFactoryUnit = parse(this.getClass().getResourceAsStream("/class-templates/TaskModelFactoryTemplate.java")); - String taskModelFactorySimpleClassName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + "TaskModelFactory"); - taskModelFactoryUnit.setPackageDeclaration(process.getPackageName()); - taskModelFactoryClassName = process.getPackageName() + "." + taskModelFactorySimpleClassName; - ClassOrInterfaceDeclaration taskModelFactoryClass = taskModelFactoryUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(IllegalStateException::new); - taskModelFactoryClass.setName(taskModelFactorySimpleClassName); - typeInterpolations.put("$TaskModelFactory$", taskModelFactoryClassName); - + protected void manageUserTasks(TemplatedGenerator.Builder templateBuilder, ClassOrInterfaceDeclaration template, + ClassOrInterfaceDeclaration taskModelFactoryClass, AtomicInteger index) { if (userTasks != null && !userTasks.isEmpty()) { CompilationUnit userTaskClazz = templateBuilder.build(context, REST_USER_TASK_TEMPLATE_NAME).compilationUnitOrThrow(); @@ -310,44 +399,42 @@ public String generate() { template.findAll(MethodDeclaration.class) .stream() .filter(md -> md.getNameAsString().equals(SIGNAL_METHOD_PREFFIX + methodSuffix)) - .collect(Collectors.toList()).forEach(template::remove); + .forEach(template::remove); } switchExpr.getEntries().add(0, userTask.getModelSwitchEntry()); } } + } - typeInterpolations.put("$Clazz$", resourceClazzName); - typeInterpolations.put("$Type$", dataClazzName); - template.findAll(StringLiteralExpr.class).forEach(this::interpolateStrings); - template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateTypes(cls, typeInterpolations)); - - TagResourceGenerator.addTags(clazz, process, context); - - template.findAll(MethodDeclaration.class).forEach(this::interpolateMethods); - - if (context.hasDI()) { - template.findAll(FieldDeclaration.class, - CodegenUtils::isProcessField).forEach(fd -> context.getDependencyInjectionAnnotator().withNamedInjection(fd, processId)); - } else { - template.findAll(FieldDeclaration.class, - CodegenUtils::isProcessField).forEach(this::initializeProcessField); - } - - // if triggers are not empty remove createResource method as there is another trigger to start process instances - if ((!startable && !dynamic) || !isPublic()) { - Optional createResourceMethod = template.findFirst(MethodDeclaration.class).filter(md -> md.getNameAsString().equals("createResource_" + processName)); - createResourceMethod.ifPresent(template::remove); - } - - if (context.hasDI()) { - context.getDependencyInjectionAnnotator().withApplicationComponent(template); + /** + * Conditionally add the Transactional annotation + * + * @param compilationUnit + * + */ + protected void manageTransactional(CompilationUnit compilationUnit) { + if (transactionEnabled && context.hasDI() && !isServerless()) { // disabling transaction for serverless + LOG.debug("Transaction is enabled, adding annotations..."); + DependencyInjectionAnnotator dependencyInjectionAnnotator = context.getDependencyInjectionAnnotator(); + getRestMethods(compilationUnit) + .forEach(dependencyInjectionAnnotator::withTransactional); } + } - enableValidation(template); - - template.getMembers().sort(new BodyDeclarationComparator()); - return clazz.toString(); + /** + * Retrieves all the Rest endpoint MethodDeclarations from the given + * CompilationUnit + * + * @param compilationUnit + * @return + */ + protected Collection getRestMethods(CompilationUnit compilationUnit) { + RestAnnotator restAnnotator = context.getRestAnnotator(); + return compilationUnit.findAll(MethodDeclaration.class) + .stream() + .filter(restAnnotator::isRestAnnotated) + .toList(); } private void securityAnnotated(ClassOrInterfaceDeclaration template) { @@ -468,4 +555,8 @@ public String generatedFilePath() { protected boolean isPublic() { return KogitoWorkflowProcess.PUBLIC_VISIBILITY.equalsIgnoreCase(process.getVisibility()); } + + protected boolean isServerless() { + return KogitoWorkflowProcess.SW_TYPE.equalsIgnoreCase(process.getType()); + } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java index 9c15e01b473..190a38af3b8 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java @@ -43,6 +43,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -55,8 +56,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; -import org.springframework.http.ResponseEntity; -import org.springframework.http.HttpStatus; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java index 57b4fa9a49a..52d1665166a 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java @@ -24,14 +24,17 @@ import java.util.Optional; import java.util.function.Predicate; +import org.assertj.core.api.ListAssert; import org.drools.io.FileSystemResource; import org.jbpm.compiler.canonical.ProcessMetaData; import org.jbpm.compiler.canonical.ProcessToExecModelGenerator; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.kie.api.definition.process.Process; import org.kie.kogito.codegen.api.AddonsConfig; import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext; import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess; import com.github.javaparser.StaticJavaParser; @@ -45,14 +48,29 @@ import com.github.javaparser.ast.expr.StringLiteralExpr; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.kie.kogito.codegen.process.ProcessResourceGenerator.INVALID_CONTEXT_TEMPLATE; class ProcessResourceGeneratorTest { + private static final String SIGNAL_METHOD = "signal_"; private static final List JAVA_AND_QUARKUS_REST_ANNOTATIONS = List.of("DELETE", "GET", "POST"); private static final List SPRING_BOOT_REST_ANNOTATIONS = List.of("DeleteMapping", "GetMapping", "PostMapping"); + @Test + void testProcessResourceGeneratorForJava() { + KogitoBuildContext.Builder contextBuilder = JavaKogitoBuildContext.builder(); + String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2"; // not relevant + boolean transactionEnabled = true; // not relevant + String expectedMessage = String.format(INVALID_CONTEXT_TEMPLATE, JavaKogitoBuildContext.CONTEXT_NAME); + assertThatThrownBy(() -> getProcessResourceGenerator(contextBuilder, fileName, + transactionEnabled)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(expectedMessage); + } + @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") void testGenerateProcessWithDocumentation(KogitoBuildContext.Builder contextBuilder) { String fileName = "src/test/resources/ProcessWithDocumentation.bpmn"; String expectedSummary = "This is the documentation"; @@ -62,7 +80,7 @@ void testGenerateProcessWithDocumentation(KogitoBuildContext.Builder contextBuil } @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") void testGenerateProcessWithoutDocumentation(KogitoBuildContext.Builder contextBuilder) { String fileName = "src/test/resources/ProcessWithoutDocumentation.bpmn"; String expectedSummary = "ProcessWithoutDocumentation"; @@ -72,7 +90,7 @@ void testGenerateProcessWithoutDocumentation(KogitoBuildContext.Builder contextB } @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") void testGenerateBoundarySignalEventOnTask(KogitoBuildContext.Builder contextBuilder) { String fileName = "src/test/resources/signalevent/BoundarySignalEventOnTask.bpmn2"; @@ -88,7 +106,7 @@ void testGenerateBoundarySignalEventOnTask(KogitoBuildContext.Builder contextBui } @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") void testGenerateStartSignalEventStringPayload(KogitoBuildContext.Builder contextBuilder) { String fileName = "src/test/resources/startsignal/StartSignalEventStringPayload.bpmn2"; String signalName = "start"; @@ -121,7 +139,7 @@ void testGenerateStartSignalEventStringPayload(KogitoBuildContext.Builder contex } @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") void testGenerateStartSignalEventNoPayload(KogitoBuildContext.Builder contextBuilder) { String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2"; String signalName = "start"; @@ -152,6 +170,68 @@ void testGenerateStartSignalEventNoPayload(KogitoBuildContext.Builder contextBui .forEach(method -> assertMethodOutputModelType(method, outputType)); } + @ParameterizedTest + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") + void testManageTransactionalEnabled(KogitoBuildContext.Builder contextBuilder) { + String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2"; + + boolean transactionEnabled = true; + ProcessResourceGenerator processResourceGenerator = getProcessResourceGenerator(contextBuilder, fileName, + transactionEnabled); + CompilationUnit compilationUnit = + processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder()); + assertThat(compilationUnit).isNotNull(); + KogitoBuildContext kogitoBuildContext = contextBuilder.build(); + Collection restEndpoints = processResourceGenerator.getRestMethods(compilationUnit); + // before processResourceGenerator.manageTransactional, the annotation is not there + testTransaction(restEndpoints, kogitoBuildContext, false); + processResourceGenerator.manageTransactional(compilationUnit); + // the annotation is (conditionally) add after processResourceGenerator.manageTransactional + testTransaction(restEndpoints, kogitoBuildContext, transactionEnabled); + } + + @ParameterizedTest + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") + void testManageTransactionalDisabled(KogitoBuildContext.Builder contextBuilder) { + String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2"; + boolean transactionEnabled = false; + ProcessResourceGenerator processResourceGenerator = getProcessResourceGenerator(contextBuilder, fileName, + transactionEnabled); + CompilationUnit compilationUnit = + processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder()); + assertThat(compilationUnit).isNotNull(); + KogitoBuildContext kogitoBuildContext = contextBuilder.build(); + Collection restEndpoints = processResourceGenerator.getRestMethods(compilationUnit); + // before processResourceGenerator.manageTransactional, the annotation is not there + testTransaction(restEndpoints, kogitoBuildContext, false); + processResourceGenerator.manageTransactional(compilationUnit); + // the annotation is (conditionally) add after processResourceGenerator.manageTransactional + testTransaction(restEndpoints, kogitoBuildContext, transactionEnabled); + } + + void testTransaction(Collection restEndpoints, + KogitoBuildContext kogitoBuildContext, + boolean enabled) { + String transactionalAnnotation = + kogitoBuildContext.getDependencyInjectionAnnotator().getTransactionalAnnotation(); + restEndpoints.forEach(methodDeclaration -> { + ListAssert transactionAnnotationAssert = assertThat( + methodDeclaration.getAnnotations().stream().filter(annotationExpr -> annotationExpr.getNameAsString().equals(transactionalAnnotation))); + if (enabled) { + transactionAnnotationAssert.hasSize(1); + } else { + transactionAnnotationAssert.isEmpty(); + } + if (methodDeclaration.getName().toString().startsWith("createResource_")) { + ListAssert stmtsAsserts = assertThat( + methodDeclaration.getBody() + .get() + .getStatements()); + stmtsAsserts.hasSize(2); + } + }); + } + void testOpenApiDocumentation(KogitoBuildContext.Builder contextBuilder, String fileName, String expectedSummary, String expectedDescription) { ClassOrInterfaceDeclaration classDeclaration = getResourceClassDeclaration(contextBuilder, fileName); @@ -168,15 +248,27 @@ private ClassOrInterfaceDeclaration getResourceClassDeclaration(KogitoBuildConte return classDeclaration.orElseThrow(); } - private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder contextBuilder, KogitoWorkflowProcess process) { + private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder contextBuilder, + KogitoWorkflowProcess process) { + ProcessResourceGenerator processResourceGenerator = getProcessResourceGenerator(contextBuilder, process, true); + return StaticJavaParser.parse(processResourceGenerator.generate()); + } + + private ProcessResourceGenerator getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder, + String fileName, boolean withTransaction) { + return getProcessResourceGenerator(contextBuilder, parseProcess(fileName), withTransaction); + } + + private ProcessResourceGenerator getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder, + KogitoWorkflowProcess process, + boolean withTransaction) { KogitoBuildContext context = createContext(contextBuilder); ProcessExecutableModelGenerator execModelGen = new ProcessExecutableModelGenerator(process, new ProcessToExecModelGenerator(context.getClassLoader())); KogitoWorkflowProcess workFlowProcess = execModelGen.process(); - - ProcessResourceGenerator processResourceGenerator = new ProcessResourceGenerator( + ProcessResourceGenerator toReturn = new ProcessResourceGenerator( context, workFlowProcess, new ModelClassGenerator(context, workFlowProcess).className(), @@ -185,11 +277,11 @@ private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder contextBui ProcessMetaData metaData = execModelGen.generate(); - processResourceGenerator + toReturn .withSignals(metaData.getSignals()) - .withTriggers(metaData.isStartable(), metaData.isDynamic(), metaData.getTriggers()); - - return StaticJavaParser.parse(processResourceGenerator.generate()); + .withTriggers(metaData.isStartable(), metaData.isDynamic(), metaData.getTriggers()) + .withTransaction(withTransaction); + return toReturn; } private void assertThatMethodHasOpenApiDocumentation(MethodDeclaration method, String summary, String description) { diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenMessageStartEventTest.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenMessageStartEventTest.java index 6badf99806b..f8c540a242a 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenMessageStartEventTest.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenMessageStartEventTest.java @@ -49,7 +49,7 @@ public class CodegenMessageStartEventTest { private static final Path MESSAGE_START_END_EVENT_SOURCE_FULL_SOURCE = BASE_PATH.resolve(MESSAGE_START_END_EVENT_SOURCE); @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") public void testRESTApiForMessageStartEvent(KogitoBuildContext.Builder contextBuilder) { KogitoBuildContext context = contextBuilder.build(); @@ -80,7 +80,7 @@ public void testRESTApiForMessageStartEvent(KogitoBuildContext.Builder contextBu } @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") public void testRESTApiForMessageEndEvent(KogitoBuildContext.Builder contextBuilder) { KogitoBuildContext context = contextBuilder.build(); diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenUserTaskTest.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenUserTaskTest.java index 271f9c897fb..24f875c2a0a 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenUserTaskTest.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/events/CodegenUserTaskTest.java @@ -43,7 +43,7 @@ public class CodegenUserTaskTest { private static final Path MESSAGE_USERTASK_SOURCE_FULL_SOURCE = BASE_PATH.resolve(MESSAGE_USERTASK_SOURCE); @ParameterizedTest - @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders") + @MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders") public void testRESTApiForMessageStartEvent(KogitoBuildContext.Builder contextBuilder) { KogitoBuildContext context = contextBuilder.build(); diff --git a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml index 9acc49370fb..60533728264 100644 --- a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml +++ b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml @@ -45,6 +45,10 @@ org.jbpm jbpm-quarkus + + io.quarkus + quarkus-narayana-jta-deployment + io.quarkus diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/pom.xml b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/pom.xml index e74b1c102b1..5caf3a85a6e 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/pom.xml +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/pom.xml @@ -68,6 +68,10 @@ io.quarkiverse.jackson-jq quarkus-jackson-jq-deployment + + io.quarkus + quarkus-narayana-jta-deployment + diff --git a/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/pom.xml b/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/pom.xml index 69118742393..736a4158584 100644 --- a/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/pom.xml +++ b/quarkus/extensions/kogito-quarkus-workflow-extension-common/kogito-quarkus-workflow-common/pom.xml @@ -45,6 +45,10 @@ io.smallrye.reactive smallrye-mutiny-vertx-web-client + + io.quarkus + quarkus-narayana-jta + org.kie.kogito jbpm-deps-group-engine diff --git a/springboot/starters/kogito-processes-spring-boot-starter/pom.xml b/springboot/starters/kogito-processes-spring-boot-starter/pom.xml index c29c25ebe10..cd9817e03ee 100644 --- a/springboot/starters/kogito-processes-spring-boot-starter/pom.xml +++ b/springboot/starters/kogito-processes-spring-boot-starter/pom.xml @@ -56,6 +56,10 @@ org.springframework.security spring-security-core + + org.springframework + spring-tx + \ No newline at end of file