From 9e83927a28cd76725136fa615bc66bae0e35a3a5 Mon Sep 17 00:00:00 2001 From: Christopher Welsch Date: Mon, 13 Jan 2025 14:10:57 +0100 Subject: [PATCH] added dedicated ParseHandler form FormAwareServiceTasks --- .../bpmn/constants/BpmnXMLConstants.java | 1 - .../cmmn/engine/CmmnEngineConfiguration.java | 2 + .../AbstractServiceTaskParseHandler.java | 64 ++ .../FormAwareServiceTaskParseHandler.java | 39 ++ .../handler/ServiceTaskParseHandler.java | 39 +- .../runtime/FormAwareServiceTaskTest.java | 578 ++++++++++++++++++ ...t.testCmmnTriggerableActivityBehavior.cmmn | 20 + ...orLifecycleListenerWithDelegateHelper.cmmn | 35 ++ ...eateFieldExpressionWithDelegateHelper.cmmn | 32 + ...viceTaskTest.testDefinitionExpression.cmmn | 40 ++ ...erviceTaskTest.testDelegateExpression.cmmn | 30 + ...erableActivityBehaviorThrowsException.cmmn | 20 + ...TaskTest.testDelegateExpressionFields.cmmn | 35 ++ ...testDelegateExpressionThrowsException.cmmn | 30 + ...askTest.testExpressionThrowsException.cmmn | 20 + ...st.testGetCmmnModelWithDelegateHelper.cmmn | 26 + ...reServiceTaskTest.testJavaServiceTask.cmmn | 26 + ...iceTaskTest.testJavaServiceTaskFields.cmmn | 35 ++ ...st.testJavaServiceTaskThrowsException.cmmn | 26 + ...erviceTaskTest.testResultVariableName.cmmn | 30 + ...ceTaskTest.testStoreTransientVariable.cmmn | 31 + .../AbstractServiceTaskParseHandler.java | 90 +++ .../FormAwareServiceTaskParseHandler.java | 42 ++ .../handler/ServiceTaskParseHandler.java | 71 +-- .../cfg/ProcessEngineConfigurationImpl.java | 2 + 25 files changed, 1257 insertions(+), 107 deletions(-) create mode 100644 modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/AbstractServiceTaskParseHandler.java create mode 100644 modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/FormAwareServiceTaskParseHandler.java create mode 100644 modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.java create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCmmnTriggerableActivityBehavior.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionForLifecycleListenerWithDelegateHelper.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionWithDelegateHelper.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDefinitionExpression.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpression.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsException.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionFields.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionThrowsException.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testExpressionThrowsException.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testGetCmmnModelWithDelegateHelper.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTask.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskFields.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskThrowsException.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testResultVariableName.cmmn create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testStoreTransientVariable.cmmn create mode 100644 modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/AbstractServiceTaskParseHandler.java create mode 100644 modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/FormAwareServiceTaskParseHandler.java diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java index 65708686a6e..74780f11237 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java @@ -86,7 +86,6 @@ public interface BpmnXMLConstants { public static final String ELEMENT_TASK_LISTENER = "taskListener"; public static final String ELEMENT_SCRIPT = "script"; public static final String ELEMENT_FORM_REFERENCE = "formreference"; - public static final String ATTRIBUTE_LISTENER_EVENT = "event"; public static final String ATTRIBUTE_LISTENER_EVENTS = "events"; public static final String ATTRIBUTE_LISTENER_ENTITY_TYPE = "entityType"; diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java index d8eee4061c9..7d6af5bcbe9 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java @@ -124,6 +124,7 @@ import org.flowable.cmmn.engine.impl.parser.handler.CaseTaskParseHandler; import org.flowable.cmmn.engine.impl.parser.handler.DecisionTaskParseHandler; import org.flowable.cmmn.engine.impl.parser.handler.ExternalWorkerServiceTaskParseHandler; +import org.flowable.cmmn.engine.impl.parser.handler.FormAwareServiceTaskParseHandler; import org.flowable.cmmn.engine.impl.parser.handler.GenericEventListenerParseHandler; import org.flowable.cmmn.engine.impl.parser.handler.HttpTaskParseHandler; import org.flowable.cmmn.engine.impl.parser.handler.HumanTaskParseHandler; @@ -1146,6 +1147,7 @@ public List getDefaultCmmnParseHandlers() { cmmnParseHandlers.add(new ProcessTaskParseHandler()); cmmnParseHandlers.add(new ScriptTaskParseHandler()); cmmnParseHandlers.add(new ServiceTaskParseHandler()); + cmmnParseHandlers.add(new FormAwareServiceTaskParseHandler()); cmmnParseHandlers.add(new SendEventServiceTaskParseHandler()); cmmnParseHandlers.add(new ExternalWorkerServiceTaskParseHandler()); cmmnParseHandlers.add(new StageParseHandler()); diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/AbstractServiceTaskParseHandler.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/AbstractServiceTaskParseHandler.java new file mode 100644 index 00000000000..82d32cac3ce --- /dev/null +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/AbstractServiceTaskParseHandler.java @@ -0,0 +1,64 @@ +/* Licensed 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.flowable.cmmn.engine.impl.parser.handler; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.cmmn.engine.impl.parser.CmmnActivityBehaviorFactory; +import org.flowable.cmmn.engine.impl.parser.CmmnParseResult; +import org.flowable.cmmn.engine.impl.parser.CmmnParserImpl; +import org.flowable.cmmn.model.HttpServiceTask; +import org.flowable.cmmn.model.ImplementationType; +import org.flowable.cmmn.model.PlanItem; +import org.flowable.cmmn.model.SendEventServiceTask; +import org.flowable.cmmn.model.ServiceTask; + +/** + * @author Joram Barrez + */ +public abstract class AbstractServiceTaskParseHandler extends AbstractPlanItemParseHandler { + + @Override + protected void executePlanItemParse(CmmnParserImpl cmmnParser, CmmnParseResult cmmnParseResult, PlanItem planItem, ServiceTask serviceTask) { + CmmnActivityBehaviorFactory activityBehaviorFactory = cmmnParser.getActivityBehaviorFactory(); + switch (serviceTask.getType()) { + case HttpServiceTask.HTTP_TASK: + planItem.setBehavior(activityBehaviorFactory.createHttpActivityBehavior(planItem, serviceTask)); + break; + + case ServiceTask.MAIL_TASK: + planItem.setBehavior(activityBehaviorFactory.createEmailActivityBehavior(planItem, serviceTask)); + break; + + case SendEventServiceTask.SEND_EVENT: + planItem.setBehavior(activityBehaviorFactory.createSendEventActivityBehavior(planItem, (SendEventServiceTask) serviceTask)); + break; + + default: + // java task type was not set in the version <= 6.2.0 that's why we have to assume that default service task type is java + if (StringUtils.isNotEmpty(serviceTask.getImplementation())) { + if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(serviceTask.getImplementationType())) { + planItem.setBehavior(activityBehaviorFactory.createCmmnClassDelegate(planItem, serviceTask)); + + } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equals(serviceTask.getImplementationType())) { + planItem.setBehavior(activityBehaviorFactory.createPlanItemExpressionActivityBehavior(planItem, serviceTask)); + + } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(serviceTask.getImplementationType())) { + planItem.setBehavior(activityBehaviorFactory.createPlanItemDelegateExpressionActivityBehavior(planItem, serviceTask)); + } + } + break; + + } + } + +} diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/FormAwareServiceTaskParseHandler.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/FormAwareServiceTaskParseHandler.java new file mode 100644 index 00000000000..6860564d8f7 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/FormAwareServiceTaskParseHandler.java @@ -0,0 +1,39 @@ +/* Licensed 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.flowable.cmmn.engine.impl.parser.handler; + +import java.util.Collection; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.cmmn.engine.impl.parser.CmmnActivityBehaviorFactory; +import org.flowable.cmmn.engine.impl.parser.CmmnParseResult; +import org.flowable.cmmn.engine.impl.parser.CmmnParserImpl; +import org.flowable.cmmn.model.BaseElement; +import org.flowable.cmmn.model.FormAwareServiceTask; +import org.flowable.cmmn.model.HttpServiceTask; +import org.flowable.cmmn.model.ImplementationType; +import org.flowable.cmmn.model.PlanItem; +import org.flowable.cmmn.model.SendEventServiceTask; +import org.flowable.cmmn.model.ServiceTask; + +/** + * @author Christopher Welsch + */ +public class FormAwareServiceTaskParseHandler extends AbstractServiceTaskParseHandler { + + @Override + public Collection> getHandledTypes() { + return Set.of(FormAwareServiceTask.class); + } +} diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/ServiceTaskParseHandler.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/ServiceTaskParseHandler.java index 2eb25f4b5f8..114691d2b7a 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/ServiceTaskParseHandler.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/handler/ServiceTaskParseHandler.java @@ -31,45 +31,10 @@ /** * @author Joram Barrez */ -public class ServiceTaskParseHandler extends AbstractPlanItemParseHandler { +public class ServiceTaskParseHandler extends AbstractServiceTaskParseHandler { @Override public Collection> getHandledTypes() { - return Set.of(ServiceTask.class, FormAwareServiceTask.class); + return Set.of(ServiceTask.class); } - - @Override - protected void executePlanItemParse(CmmnParserImpl cmmnParser, CmmnParseResult cmmnParseResult, PlanItem planItem, ServiceTask serviceTask) { - CmmnActivityBehaviorFactory activityBehaviorFactory = cmmnParser.getActivityBehaviorFactory(); - switch (serviceTask.getType()) { - case HttpServiceTask.HTTP_TASK: - planItem.setBehavior(activityBehaviorFactory.createHttpActivityBehavior(planItem, serviceTask)); - break; - - case ServiceTask.MAIL_TASK: - planItem.setBehavior(activityBehaviorFactory.createEmailActivityBehavior(planItem, serviceTask)); - break; - - case SendEventServiceTask.SEND_EVENT: - planItem.setBehavior(activityBehaviorFactory.createSendEventActivityBehavior(planItem, (SendEventServiceTask) serviceTask)); - break; - - default: - // java task type was not set in the version <= 6.2.0 that's why we have to assume that default service task type is java - if (StringUtils.isNotEmpty(serviceTask.getImplementation())) { - if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(serviceTask.getImplementationType())) { - planItem.setBehavior(activityBehaviorFactory.createCmmnClassDelegate(planItem, serviceTask)); - - } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equals(serviceTask.getImplementationType())) { - planItem.setBehavior(activityBehaviorFactory.createPlanItemExpressionActivityBehavior(planItem, serviceTask)); - - } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(serviceTask.getImplementationType())) { - planItem.setBehavior(activityBehaviorFactory.createPlanItemDelegateExpressionActivityBehavior(planItem, serviceTask)); - } - } - break; - - } - } - } diff --git a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.java b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.java new file mode 100644 index 00000000000..7e26b3d995f --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.java @@ -0,0 +1,578 @@ +/* Licensed 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.flowable.cmmn.test.runtime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.assertj.core.api.InstanceOfAssertFactories; +import org.flowable.cmmn.api.delegate.DelegatePlanItemInstance; +import org.flowable.cmmn.api.delegate.PlanItemJavaDelegate; +import org.flowable.cmmn.api.listener.PlanItemInstanceLifecycleListener; +import org.flowable.cmmn.api.runtime.CaseInstance; +import org.flowable.cmmn.api.runtime.PlanItemInstance; +import org.flowable.cmmn.api.runtime.PlanItemInstanceState; +import org.flowable.cmmn.engine.impl.behavior.CmmnTriggerableActivityBehavior; +import org.flowable.cmmn.engine.impl.delegate.CmmnDelegateHelper; +import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity; +import org.flowable.cmmn.engine.impl.util.CommandContextUtil; +import org.flowable.cmmn.engine.test.CmmnDeployment; +import org.flowable.cmmn.engine.test.FlowableCmmnTestCase; +import org.flowable.cmmn.engine.test.impl.CmmnHistoryTestHelper; +import org.flowable.cmmn.model.CmmnElement; +import org.flowable.cmmn.model.CmmnModel; +import org.flowable.cmmn.model.PlanItem; +import org.flowable.cmmn.test.delegate.TestJavaDelegateThrowsException; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.api.FlowableIllegalArgumentException; +import org.flowable.common.engine.api.delegate.Expression; +import org.flowable.common.engine.impl.history.HistoryLevel; +import org.flowable.common.engine.impl.javax.el.ELException; +import org.flowable.variable.api.history.HistoricVariableInstance; +import org.flowable.variable.api.persistence.entity.VariableInstance; +import org.junit.Test; + +/** + * @author Tijs Rademakers + * @author Joram Barrez + */ +public class FormAwareServiceTaskTest extends FlowableCmmnTestCase { + + @Test + @CmmnDeployment + public void testJavaServiceTask() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .variable("test", "test2") + .start(); + assertThat(caseInstance).isNotNull(); + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + assertThat(planItemInstance).isNotNull(); + + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "javaDelegate")).isEqualTo("executed"); + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "test")).isEqualTo("test2"); + + assertThat(cmmnRuntimeService.createVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("javaDelegate") + .singleResult().getValue()).isEqualTo("executed"); + + // Triggering the task should start the child case instance + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("javaDelegate") + .singleResult().getValue()).isEqualTo("executed"); + } + } + + @Test + @CmmnDeployment + public void testJavaServiceTaskFields() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .variable("test", "test") + .start(); + assertThat(caseInstance).isNotNull(); + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + assertThat(planItemInstance).isNotNull(); + + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "testValue")).isEqualTo("test"); + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "testExpression")).isEqualTo(true); + + // Triggering the task should start the child case instance + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("testValue") + .singleResult().getValue()).isEqualTo("test"); + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("testExpression") + .singleResult().getValue()).isEqualTo(true); + } + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testJavaServiceTaskThrowsException.cmmn") + public void testJavaServiceTaskThrowsFlowableException() { + TestJavaDelegateThrowsException.setExceptionSupplier(() -> new FlowableIllegalArgumentException("test exception")); + assertThatThrownBy(() -> cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start()) + .isInstanceOf(FlowableIllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + + TestJavaDelegateThrowsException.resetExceptionSupplier(); + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testJavaServiceTaskThrowsException.cmmn") + public void testJavaServiceTaskThrowsNonFlowableException() { + TestJavaDelegateThrowsException.setExceptionSupplier(() -> new IllegalArgumentException("test exception")); + assertThatThrownBy(() -> cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start()) + .isInstanceOf(IllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + TestJavaDelegateThrowsException.resetExceptionSupplier(); + } + + @Test + @CmmnDeployment + public void testResultVariableName() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .variable("test", "test") + .start(); + assertThat(caseInstance).isNotNull(); + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + assertThat(planItemInstance).isNotNull(); + + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "beanResponse")).isEqualTo("hello test"); + + // Triggering the task should start the child case instance + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("beanResponse") + .singleResult().getValue()).isEqualTo("hello test"); + } + } + + @Test + @CmmnDeployment + public void testDefinitionExpression() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start(); + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + + planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + assertThat(planItemInstance).isNotNull(); + + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "resultVersion")).isEqualTo("1"); + assertThat(cmmnRuntimeService.getVariableInstance(caseInstance.getId(), "resultVersion").getTypeName()).isEqualTo("string"); + + VariableInstance variableInstance = cmmnRuntimeService.createVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("resultVersion") + .singleResult(); + + assertThat(variableInstance.getValue()).isEqualTo("1"); + assertThat(variableInstance.getTypeName()).isEqualTo("string"); + + // Triggering the task should start the child case instance + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + HistoricVariableInstance historicVariableInstance = cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("resultVersion") + .singleResult(); + + assertThat(historicVariableInstance.getValue()).isEqualTo("1"); + assertThat(historicVariableInstance.getVariableTypeName()).isEqualTo("string"); + } + } + + @Test + @CmmnDeployment + public void testDelegateExpression() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .variable("test", "test2") + .start(); + assertThat(caseInstance).isNotNull(); + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + assertThat(planItemInstance).isNotNull(); + + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "javaDelegate")).isEqualTo("executed"); + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "test")).isEqualTo("test2"); + + // Triggering the task should start the child case instance + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("javaDelegate") + .singleResult().getValue()).isEqualTo("executed"); + } + } + + @Test + @CmmnDeployment + public void testDelegateExpressionFields() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .variable("test", "test") + .start(); + assertThat(caseInstance).isNotNull(); + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .planItemInstanceState(PlanItemInstanceState.ACTIVE) + .singleResult(); + assertThat(planItemInstance).isNotNull(); + + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "testValue")).isEqualTo("test"); + assertThat(cmmnRuntimeService.getVariable(caseInstance.getId(), "testExpression")).isEqualTo(true); + + // Triggering the task should start the child case instance + cmmnRuntimeService.triggerPlanItemInstance(planItemInstance.getId()); + assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("testValue") + .singleResult().getValue()).isEqualTo("test"); + assertThat(cmmnHistoryService.createHistoricVariableInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .variableName("testExpression") + .singleResult().getValue()).isEqualTo(true); + } + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testDelegateExpressionThrowsException.cmmn") + public void testDelegateExpressionThrowsFlowableException() { + assertThatThrownBy(() -> cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .transientVariable("testDelegateBeanThrowsException", new PlanItemJavaDelegate() { + + @Override + public void execute(DelegatePlanItemInstance planItemInstance) { + throw new FlowableIllegalArgumentException("test exception"); + } + }) + .start()) + .isInstanceOf(FlowableIllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testDelegateExpressionThrowsException.cmmn") + public void testDelegateExpressionThrowsNonFlowableException() { + assertThatThrownBy(() -> cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .transientVariable("testDelegateBeanThrowsException", new PlanItemJavaDelegate() { + + @Override + public void execute(DelegatePlanItemInstance planItemInstance) { + throw new IllegalArgumentException("test exception"); + } + }) + .start()) + .isInstanceOf(IllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsException.cmmn") + public void testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsFlowableExceptionOnTrigger() { + CmmnTriggerableActivityBehavior triggerableActivityBehavior = new CmmnTriggerableActivityBehavior() { + + @Override + public void trigger(DelegatePlanItemInstance planItemInstance) { + throw new FlowableIllegalArgumentException("test exception"); + } + + @Override + public void execute(DelegatePlanItemInstance delegatePlanItemInstance) { + // Do nothing, wait state + } + }; + + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .transientVariable("testDelegateBeanThrowsException", triggerableActivityBehavior) + .start(); + + // The service task here acts like a wait state. + // When the case instance is started, it will wait and be in state ACTIVE. + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(planItemInstance.getState()).isEqualTo(PlanItemInstanceState.ACTIVE); + + // When triggered, the plan item will complete + assertThatThrownBy(() -> { + cmmnRuntimeService.createPlanItemInstanceTransitionBuilder(planItemInstance.getId()) + .transientVariable("testDelegateBeanThrowsException", triggerableActivityBehavior) + .trigger(); + }) + .isInstanceOf(FlowableIllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsException.cmmn") + public void testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsNonFlowableExceptionOnTrigger() { + CmmnTriggerableActivityBehavior triggerableActivityBehavior = new CmmnTriggerableActivityBehavior() { + + @Override + public void trigger(DelegatePlanItemInstance planItemInstance) { + throw new IllegalArgumentException("test exception"); + } + + @Override + public void execute(DelegatePlanItemInstance delegatePlanItemInstance) { + // Do nothing, wait state + } + }; + + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .transientVariable("testDelegateBeanThrowsException", triggerableActivityBehavior) + .start(); + + // The service task here acts like a wait state. + // When the case instance is started, it will wait and be in state ACTIVE. + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(planItemInstance.getState()).isEqualTo(PlanItemInstanceState.ACTIVE); + + // When triggered, the plan item will complete + assertThatThrownBy(() -> { + cmmnRuntimeService.createPlanItemInstanceTransitionBuilder(planItemInstance.getId()) + .transientVariable("testDelegateBeanThrowsException", triggerableActivityBehavior) + .trigger(); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + } + + @Test + @CmmnDeployment + public void testGetCmmnModelWithDelegateHelper() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start(); + + assertThat(TestJavaDelegate01.cmmnModel).isNotNull(); + assertThat(TestJavaDelegate01.cmmnElement) + .asInstanceOf(InstanceOfAssertFactories.type(PlanItem.class)) + .extracting(PlanItem::getName) + .isEqualTo("Task One"); + } + + @Test + @CmmnDeployment + public void testCreateFieldExpressionWithDelegateHelper() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start(); + + Number variable = (Number) cmmnRuntimeService.getVariable(caseInstance.getId(), "delegateVariable"); + assertThat(variable).isEqualTo(2L); + } + + @Test + @CmmnDeployment + public void testCreateFieldExpressionForLifecycleListenerWithDelegateHelper() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start(); + + Number variable = (Number) cmmnRuntimeService.getVariable(caseInstance.getId(), "listenerVar"); + assertThat(variable).isEqualTo(99L); + } + + @Test + @CmmnDeployment + public void testStoreTransientVariable() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start(); + + Object transientResult = cmmnRuntimeService.getVariable(caseInstance.getId(), "transientResult"); + Object persistentResult = cmmnRuntimeService.getVariable(caseInstance.getId(), "persistentResult"); + + assertThat(transientResult).isNull(); + assertThat(persistentResult).isEqualTo("Result is: test"); + } + + @Test + @CmmnDeployment + public void testCmmnTriggerableActivityBehavior() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .start(); + + // The service task here acts like a wait state. + // When the case instance is started, it will wait and be in state ACTIVE. + + PlanItemInstance planItemInstance = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(planItemInstance.getState()).isEqualTo(PlanItemInstanceState.ACTIVE); + + // When triggered, the plan item will complete + cmmnRuntimeService.createPlanItemInstanceTransitionBuilder(planItemInstance.getId()).trigger(); + + assertCaseInstanceEnded(caseInstance); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricPlanItemInstanceQuery().planItemInstanceCaseInstanceId(caseInstance.getId()).singleResult().getState()) + .isEqualTo(PlanItemInstanceState.COMPLETED); + } + + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testExpressionThrowsException.cmmn") + public void testExpressionThrowsFlowableException() { + assertThatThrownBy(() -> cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .transientVariable("testBean", new Object() { + + public void invoke() { + throw new FlowableIllegalArgumentException("test exception"); + } + }) + .start()) + .isExactlyInstanceOf(FlowableException.class) + .hasMessageStartingWith("Error while evaluating expression: ${testBean.invoke()} with PlanItemInstance with id: ") + .hasMessageContainingAll("name: Task One", "definitionId: serviceTask", "state: active", "elementId: planItem1", + "caseInstanceId: ", "caseDefinitionId: ") + .cause() + .isInstanceOf(ELException.class) + .cause() + .isInstanceOf(FlowableIllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + } + + @Test + @CmmnDeployment(resources = "org/flowable/cmmn/test/runtime/ServiceTaskTest.testExpressionThrowsException.cmmn") + public void testExpressionThrowsNonFlowableException() { + assertThatThrownBy(() -> cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("myCase") + .transientVariable("testBean", new Object() { + + public void invoke() { + throw new IllegalArgumentException("test exception"); + } + }) + .start()) + .isExactlyInstanceOf(FlowableException.class) + .hasMessageStartingWith("Error while evaluating expression: ${testBean.invoke()} with PlanItemInstance with id: ") + .hasMessageContainingAll("name: Task One", "definitionId: serviceTask", "state: active", "elementId: planItem1", + "caseInstanceId: ", "caseDefinitionId: ") + .cause() + .isInstanceOf(ELException.class) + .cause() + .isInstanceOf(IllegalArgumentException.class) + .hasNoCause() + .hasMessage("test exception"); + } + + public static class TestJavaDelegate01 implements PlanItemJavaDelegate { + + public static CmmnModel cmmnModel; + public static CmmnElement cmmnElement; + + @Override + public void execute(DelegatePlanItemInstance planItemInstance) { + cmmnModel = CmmnDelegateHelper.getCmmnModel(planItemInstance); + cmmnElement = CmmnDelegateHelper.getCmmnElement(planItemInstance); + } + + } + + public static class TestJavaDelegate02 implements PlanItemJavaDelegate { + + @Override + public void execute(DelegatePlanItemInstance planItemInstance) { + Expression delegateFieldExpression = CmmnDelegateHelper.getFieldExpression(planItemInstance, "delegateField"); + planItemInstance.setVariable("delegateVariable", delegateFieldExpression.getValue(planItemInstance)); + + } + + } + + public static class TestJavaDelegate03 implements CmmnTriggerableActivityBehavior { + + @Override + public void execute(DelegatePlanItemInstance delegatePlanItemInstance) { + // Do nothing, wait state + } + + @Override + public void trigger(DelegatePlanItemInstance planItemInstance) { + CommandContextUtil.getAgenda().planCompletePlanItemInstanceOperation((PlanItemInstanceEntity) planItemInstance); + } + + } + + public static class TestLifecycleListener01 implements PlanItemInstanceLifecycleListener { + + @Override + public String getSourceState() { + return null; + } + + @Override + public String getTargetState() { + return null; + } + + @Override + public void stateChanged(DelegatePlanItemInstance planItemInstance, String oldState, String newState) { + Expression delegateField = CmmnDelegateHelper.getFieldExpression(planItemInstance, "delegateField"); + planItemInstance.setVariable("listenerVar", delegateField.getValue(planItemInstance)); + } + + } + +} diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCmmnTriggerableActivityBehavior.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCmmnTriggerableActivityBehavior.cmmn new file mode 100644 index 00000000000..a2c65c58f92 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCmmnTriggerableActivityBehavior.cmmn @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionForLifecycleListenerWithDelegateHelper.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionForLifecycleListenerWithDelegateHelper.cmmn new file mode 100644 index 00000000000..ae8b6a7db52 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionForLifecycleListenerWithDelegateHelper.cmmn @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionWithDelegateHelper.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionWithDelegateHelper.cmmn new file mode 100644 index 00000000000..6cf97bf276f --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testCreateFieldExpressionWithDelegateHelper.cmmn @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDefinitionExpression.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDefinitionExpression.cmmn new file mode 100644 index 00000000000..37ecdda5782 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDefinitionExpression.cmmn @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + complete + + + + + + complete + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpression.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpression.cmmn new file mode 100644 index 00000000000..c8f4c52196b --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpression.cmmn @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsException.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsException.cmmn new file mode 100644 index 00000000000..17416f0a799 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionCmmnTriggerableActivityBehaviorThrowsException.cmmn @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionFields.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionFields.cmmn new file mode 100644 index 00000000000..962980a4160 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionFields.cmmn @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionThrowsException.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionThrowsException.cmmn new file mode 100644 index 00000000000..d1932b2917b --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testDelegateExpressionThrowsException.cmmn @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testExpressionThrowsException.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testExpressionThrowsException.cmmn new file mode 100644 index 00000000000..2a5dd522d3e --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testExpressionThrowsException.cmmn @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testGetCmmnModelWithDelegateHelper.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testGetCmmnModelWithDelegateHelper.cmmn new file mode 100644 index 00000000000..f704abd3a30 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testGetCmmnModelWithDelegateHelper.cmmn @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTask.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTask.cmmn new file mode 100644 index 00000000000..c994971c9ad --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTask.cmmn @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskFields.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskFields.cmmn new file mode 100644 index 00000000000..ec40e4af8a6 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskFields.cmmn @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskThrowsException.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskThrowsException.cmmn new file mode 100644 index 00000000000..a3aa8b0db1c --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testJavaServiceTaskThrowsException.cmmn @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testResultVariableName.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testResultVariableName.cmmn new file mode 100644 index 00000000000..3d460040c5f --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testResultVariableName.cmmn @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testStoreTransientVariable.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testStoreTransientVariable.cmmn new file mode 100644 index 00000000000..bbdd887e960 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/FormAwareServiceTaskTest.testStoreTransientVariable.cmmn @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/AbstractServiceTaskParseHandler.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/AbstractServiceTaskParseHandler.java new file mode 100644 index 00000000000..7c3a714967a --- /dev/null +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/AbstractServiceTaskParseHandler.java @@ -0,0 +1,90 @@ +/* Licensed 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.flowable.engine.impl.bpmn.parser.handler; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.bpmn.model.ImplementationType; +import org.flowable.bpmn.model.ServiceTask; +import org.flowable.engine.impl.bpmn.behavior.WebServiceActivityBehavior; +import org.flowable.engine.impl.bpmn.parser.BpmnParse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Christopher Welsch + */ +public abstract class AbstractServiceTaskParseHandler extends AbstractActivityBpmnParseHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractServiceTaskParseHandler.class); + + @Override + protected void executeParse(BpmnParse bpmnParse, T serviceTask) { + + // Email, Http and Shell service tasks + if (StringUtils.isNotEmpty(serviceTask.getType())) { + + if ("mail".equalsIgnoreCase(serviceTask.getType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createMailActivityBehavior(serviceTask)); + + } else if ("camel".equalsIgnoreCase(serviceTask.getType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createCamelActivityBehavior(serviceTask)); + + } else if ("shell".equalsIgnoreCase(serviceTask.getType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createShellActivityBehavior(serviceTask)); + + } else if ("dmn".equalsIgnoreCase(serviceTask.getType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createDmnActivityBehavior(serviceTask)); + + } else if ("http".equalsIgnoreCase(serviceTask.getType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createHttpActivityBehavior(serviceTask)); + + } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskDelegateExpressionActivityBehavior(serviceTask)); + + } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskExpressionActivityBehavior(serviceTask)); + + } else { + LOGGER.warn("Invalid type: '{}' for service task {}", serviceTask.getType(), serviceTask.getId()); + } + + // flowable:class + } else if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(serviceTask.getImplementationType())) { + + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createClassDelegateServiceTask(serviceTask)); + + // flowable:delegateExpression + } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { + + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskDelegateExpressionActivityBehavior(serviceTask)); + + // flowable:expression + } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { + + serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskExpressionActivityBehavior(serviceTask)); + + // Webservice + } else if (ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE.equalsIgnoreCase(serviceTask.getImplementationType()) && StringUtils.isNotEmpty( + serviceTask.getOperationRef())) { + + WebServiceActivityBehavior webServiceActivityBehavior = bpmnParse.getActivityBehaviorFactory() + .createWebServiceActivityBehavior(serviceTask, bpmnParse.getBpmnModel()); + serviceTask.setBehavior(webServiceActivityBehavior); + + } else { + LOGGER.warn("One of the attributes 'class', 'delegateExpression', 'type', 'operation', or 'expression' is mandatory on service task {}", + serviceTask.getId()); + } + + } +} diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/FormAwareServiceTaskParseHandler.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/FormAwareServiceTaskParseHandler.java new file mode 100644 index 00000000000..a5bb2b86588 --- /dev/null +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/FormAwareServiceTaskParseHandler.java @@ -0,0 +1,42 @@ +/* Licensed 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.flowable.engine.impl.bpmn.parser.handler; + +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.bpmn.model.BaseElement; +import org.flowable.bpmn.model.FormAwareServiceTask; +import org.flowable.bpmn.model.ImplementationType; +import org.flowable.bpmn.model.ServiceTask; +import org.flowable.engine.impl.bpmn.behavior.WebServiceActivityBehavior; +import org.flowable.engine.impl.bpmn.parser.BpmnParse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Christopher Welsch + */ +public class FormAwareServiceTaskParseHandler extends AbstractServiceTaskParseHandler { + + @Override + public Class getHandledType() { + return FormAwareServiceTask.class; + } + + @Override + public Set> getHandledTypes() { + return Set.of(FormAwareServiceTask.class); + } + +} diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/ServiceTaskParseHandler.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/ServiceTaskParseHandler.java index 8fe571aad3a..1a7fcece5d2 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/ServiceTaskParseHandler.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/handler/ServiceTaskParseHandler.java @@ -14,22 +14,13 @@ import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.flowable.bpmn.model.BaseElement; -import org.flowable.bpmn.model.FormAwareServiceTask; -import org.flowable.bpmn.model.ImplementationType; import org.flowable.bpmn.model.ServiceTask; -import org.flowable.engine.impl.bpmn.behavior.WebServiceActivityBehavior; -import org.flowable.engine.impl.bpmn.parser.BpmnParse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author Joram Barrez */ -public class ServiceTaskParseHandler extends AbstractActivityBpmnParseHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTaskParseHandler.class); +public class ServiceTaskParseHandler extends AbstractServiceTaskParseHandler { @Override public Class getHandledType() { @@ -38,64 +29,6 @@ public Class getHandledType() { @Override public Set> getHandledTypes() { - return Set.of(ServiceTask.class, FormAwareServiceTask.class); - } - - @Override - protected void executeParse(BpmnParse bpmnParse, ServiceTask serviceTask) { - - // Email, Http and Shell service tasks - if (StringUtils.isNotEmpty(serviceTask.getType())) { - - if ("mail".equalsIgnoreCase(serviceTask.getType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createMailActivityBehavior(serviceTask)); - - } else if ("camel".equalsIgnoreCase(serviceTask.getType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createCamelActivityBehavior(serviceTask)); - - } else if ("shell".equalsIgnoreCase(serviceTask.getType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createShellActivityBehavior(serviceTask)); - - } else if ("dmn".equalsIgnoreCase(serviceTask.getType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createDmnActivityBehavior(serviceTask)); - - } else if ("http".equalsIgnoreCase(serviceTask.getType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createHttpActivityBehavior(serviceTask)); - - } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskDelegateExpressionActivityBehavior(serviceTask)); - - } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskExpressionActivityBehavior(serviceTask)); - - } else { - LOGGER.warn("Invalid type: '{}' for service task {}", serviceTask.getType(), serviceTask.getId()); - } - - // flowable:class - } else if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(serviceTask.getImplementationType())) { - - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createClassDelegateServiceTask(serviceTask)); - - // flowable:delegateExpression - } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { - - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskDelegateExpressionActivityBehavior(serviceTask)); - - // flowable:expression - } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) { - - serviceTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskExpressionActivityBehavior(serviceTask)); - - // Webservice - } else if (ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE.equalsIgnoreCase(serviceTask.getImplementationType()) && StringUtils.isNotEmpty(serviceTask.getOperationRef())) { - - WebServiceActivityBehavior webServiceActivityBehavior = bpmnParse.getActivityBehaviorFactory().createWebServiceActivityBehavior(serviceTask, bpmnParse.getBpmnModel()); - serviceTask.setBehavior(webServiceActivityBehavior); - - } else { - LOGGER.warn("One of the attributes 'class', 'delegateExpression', 'type', 'operation', or 'expression' is mandatory on service task {}", serviceTask.getId()); - } - + return Set.of(ServiceTask.class); } } diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java index abca90fe54a..ed3aa7c0d5a 100755 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java @@ -190,6 +190,7 @@ import org.flowable.engine.impl.bpmn.parser.handler.EventSubProcessParseHandler; import org.flowable.engine.impl.bpmn.parser.handler.ExclusiveGatewayParseHandler; import org.flowable.engine.impl.bpmn.parser.handler.ExternalWorkerServiceTaskParseHandler; +import org.flowable.engine.impl.bpmn.parser.handler.FormAwareServiceTaskParseHandler; import org.flowable.engine.impl.bpmn.parser.handler.HttpServiceTaskParseHandler; import org.flowable.engine.impl.bpmn.parser.handler.InclusiveGatewayParseHandler; import org.flowable.engine.impl.bpmn.parser.handler.IntermediateCatchEventParseHandler; @@ -1830,6 +1831,7 @@ public List getDefaultBpmnParseHandlers() { bpmnParserHandlers.add(new SendTaskParseHandler()); bpmnParserHandlers.add(new SequenceFlowParseHandler()); bpmnParserHandlers.add(new ServiceTaskParseHandler()); + bpmnParserHandlers.add(new FormAwareServiceTaskParseHandler()); bpmnParserHandlers.add(new HttpServiceTaskParseHandler()); bpmnParserHandlers.add(new SignalEventDefinitionParseHandler()); bpmnParserHandlers.add(new StartEventParseHandler());