public SubProcessBuilder builder() { return new SubProcessBuilder((BpmnModelInstance) modelInstance, this); }
public static final BpmnModelInstance subProcessProcess(String key) { return Bpmn.createExecutableProcess(key) .startEvent() .subProcess() .camundaExecutionListenerClass(ExecutionListener.EVENTNAME_START, InstantiationListener.class.getName()) .camundaExecutionListenerClass(ExecutionListener.EVENTNAME_END, RemovalListener.class.getName()) .embeddedSubProcess() .startEvent() .userTask("userTask") .endEvent() .subProcessDone() .endEvent() .done(); }
@Test public void testSetVariableOnStartExecutionListenerInSubProcessWithBoundary() { BpmnModelInstance modelInstance = Bpmn.createExecutableProcess(CONDITIONAL_EVENT_PROCESS_KEY) .startEvent() .subProcess(SUB_PROCESS_ID) .camundaExecutionListenerExpression(ExecutionListener.EVENTNAME_START, EXPR_SET_VARIABLE) .embeddedSubProcess() .startEvent() .userTask(TASK_WITH_CONDITION_ID) .name(TASK_WITH_CONDITION) .endEvent() .subProcessDone() .endEvent() .done(); modelInstance = addEventSubProcess(modelInstance, SUB_PROCESS_ID, TASK_AFTER_COND_START_EVENT_IN_SUB_PROCESS, true); deployMixedProcess(modelInstance, CONDITIONAL_EVENT_PROCESS_KEY, SUB_PROCESS_ID, true); // given ProcessInstance procInst = runtimeService.startProcessInstanceByKey(CONDITIONAL_EVENT_PROCESS_KEY); TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(procInst.getId()); //when start listener sets variable //then conditional boundary should not triggered but conditional start event tasksAfterVariableIsSet = taskQuery.list(); assertEquals(TASK_AFTER_CONDITIONAL_START_EVENT, tasksAfterVariableIsSet.get(0).getName()); }
@Override public MigratingBpmnEventTrigger addEventSubProcess(ProcessEngine engine, BpmnModelInstance modelInstance, String parentId, String subProcessId, String startEventId) { ModifiableBpmnModelInstance.wrap(modelInstance) .addSubProcessTo(parentId) .id(subProcessId) .triggerByEvent() .embeddedSubProcess() .startEvent(startEventId).signal(SIGNAL_NAME) .subProcessDone() .done(); SignalTrigger trigger = new SignalTrigger(); trigger.engine = engine; trigger.signalName = SIGNAL_NAME; trigger.activityId = startEventId; return trigger; }
@Override public BpmnModelInstance getSourceProcess() { return modify(ProcessModels.SUBPROCESS_PROCESS) .addSubProcessTo(EventSubProcessModels.SUB_PROCESS_ID) .triggerByEvent() .embeddedSubProcess() .startEvent(EVENT_SUB_PROCESS_START_ID).signal(EventSubProcessModels.SIGNAL_NAME) .userTask(EVENT_SUB_PROCESS_TASK_ID) .endEvent() .subProcessDone() .done(); }
public void testPropagateTenantIdToEmbeddedSubprocess() { deploymentForTenant(TENANT_ID, Bpmn.createExecutableProcess(PROCESS_DEFINITION_KEY) .startEvent() .subProcess() .embeddedSubProcess() .startEvent() .userTask() .endEvent() .subProcessDone() .endEvent() .done()); startProcessInstance(PROCESS_DEFINITION_KEY); List<Execution> executions = runtimeService.createExecutionQuery().list(); assertThat(executions.size(), is(2)); assertThat(executions.get(0).getTenantId(), is(TENANT_ID)); // inherit the tenant id from parent execution (e.g. process instance) assertThat(executions.get(1).getTenantId(), is(TENANT_ID)); }
@Test public void testSetVariableOnInputMappingInSubProcessWithBoundary() { BpmnModelInstance modelInstance = Bpmn.createExecutableProcess(CONDITIONAL_EVENT_PROCESS_KEY) .startEvent() .subProcess(SUB_PROCESS_ID) .camundaInputParameter(VARIABLE_NAME, "1") .embeddedSubProcess() .startEvent() .userTask(TASK_WITH_CONDITION_ID) .name(TASK_WITH_CONDITION) .endEvent() .subProcessDone() .endEvent() .done(); modelInstance = addEventSubProcess(modelInstance, SUB_PROCESS_ID, TASK_AFTER_COND_START_EVENT_IN_SUB_PROCESS, true); deployMixedProcess(modelInstance, CONDITIONAL_EVENT_PROCESS_KEY, SUB_PROCESS_ID, true); // given ProcessInstance procInst = runtimeService.startProcessInstanceByKey(CONDITIONAL_EVENT_PROCESS_KEY); TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(procInst.getId()); //when input mapping sets variable //then conditional boundary event should triggered from the default evaluation behavior // The event sub process inside the sub process should not since the scope is lower than from the boundary. // The global event sub process should not since the variable is only locally. tasksAfterVariableIsSet = taskQuery.list(); assertEquals(1, tasksAfterVariableIsSet.size()); assertEquals(TASK_AFTER_CONDITIONAL_BOUNDARY_EVENT, tasksAfterVariableIsSet.get(0).getName()); }
.triggerByEvent() .embeddedSubProcess() .startEvent(EVENT_SUB_PROCESS_START_ID) .condition(VAR_CONDITION) .startEvent() .subProcess(SUB_PROCESS_ID) .camundaExecutionListenerClass(ExecutionListener.EVENTNAME_START, SetVariableDelegate.class.getName()) .embeddedSubProcess() .startEvent() .userTask(USER_TASK_ID) .endEvent() .subProcessDone() .endEvent() .done()) .addSubProcessTo(SUB_PROCESS_ID) .triggerByEvent() .embeddedSubProcess() .startEvent() .condition(VAR_CONDITION) .triggerByEvent() .embeddedSubProcess() .startEvent(EVENT_SUB_PROCESS_START_ID) .condition(VAR_CONDITION)
protected void deployConditionalEventSubProcess(BpmnModelInstance model, String parentId, boolean isInterrupting) { final BpmnModelInstance modelInstance = modify(model) .addSubProcessTo(parentId) .id("eventSubProcess") .triggerByEvent() .embeddedSubProcess() .startEvent() .interrupting(isInterrupting) .conditionalEventDefinition(CONDITIONAL_EVENT) .condition(CONDITION_EXPR) .conditionalEventDefinitionDone() .userTask("taskAfterCond") .name(TASK_AFTER_CONDITION) .endEvent().done(); engine.manageDeployment(repositoryService.createDeployment().addModelInstance(CONDITIONAL_MODEL, modelInstance).deploy()); }
protected BpmnModelInstance addConditionalEventSubProcess(BpmnModelInstance model, String parentId, String conditionExpr, String userTaskId, boolean isInterrupting) { return modify(model) .addSubProcessTo(parentId) .triggerByEvent() .embeddedSubProcess() .startEvent() .interrupting(isInterrupting) .condition(conditionExpr) .userTask(userTaskId) .name(TASK_AFTER_CONDITION) .endEvent().done(); }
.subProcess("subProcess").camundaAsyncBefore() .embeddedSubProcess() .startEvent() .serviceTask("task").camundaAsyncBefore().camundaExpression("${true}") .endEvent() .subProcessDone() .endEvent("end").camundaAsyncBefore() .done() );
.subProcess("subProcess").camundaAsyncAfter() .embeddedSubProcess() .startEvent() .serviceTask("task").camundaAsyncAfter().camundaExpression("${true}") .endEvent() .subProcessDone() .endEvent("end").camundaAsyncAfter() .done() );
.startEvent("start") .subProcess("subProcess") .embeddedSubProcess() .startEvent("subProcessStart") .endEvent("subProcessEnd") .subProcessDone() .userTask("userTask") .done(); .id("eventSubProcess") .triggerByEvent() .embeddedSubProcess() .startEvent() .compensateEventDefinition()
.startEvent() .subProcess("outerSubProcess") .embeddedSubProcess() .startEvent() .userTask("userTask1") .moveToActivity("userTask1") .subProcess("innerSubProcess") .embeddedSubProcess() .startEvent() .userTask("userTask2") .endEvent() .subProcessDone() .endEvent() .subProcessDone() .done(); CompensationModels.addUserTaskCompensationHandler(sourceModel, "compensationBoundary", "compensationHandler");
@Test public void testCompensationBoundaryHierarchyPreservation() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.COMPENSATION_ONE_TASK_SUBPROCESS_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(modify(CompensationModels.COMPENSATION_ONE_TASK_SUBPROCESS_MODEL) .addSubProcessTo(ProcessModels.PROCESS_KEY) .id("addedSubProcess") .embeddedSubProcess() .startEvent() .endEvent() .done()); try { // when rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("subProcess", "addedSubProcess") .mapActivities("compensationBoundary", "compensationBoundary") .build(); Assert.fail("exception expected"); } catch (MigrationPlanValidationException e) { // then assertThat(e.getValidationReport()) .hasInstructionFailures("compensationBoundary", "The closest mapped ancestor 'subProcess' is mapped to scope 'addedSubProcess' " + "which is not an ancestor of target scope 'compensationBoundary'" ); } }
public static BpmnModelInstance prepareCompensationEventProcess() { return Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .subProcess("subProcess") .embeddedSubProcess() .startEvent() .endEvent() .subProcessDone() .intermediateThrowEvent(FAILING_EVENT) .camundaAsyncBefore(true) .camundaFailedJobRetryTimeCycle(SCHEDULE) .compensateEventDefinition() .compensateEventDefinitionDone() .serviceTask() .camundaClass(FailingDelegate.class.getName()) .endEvent() .done(); }
@Override public MigratingBpmnEventTrigger addEventSubProcess(ProcessEngine engine, BpmnModelInstance modelInstance, String parentId, String subProcessId, String startEventId) { ModifiableBpmnModelInstance.wrap(modelInstance) .addSubProcessTo(parentId) .id(subProcessId) .triggerByEvent() .embeddedSubProcess() .startEvent(startEventId).message(MESSAGE_NAME) .subProcessDone() .done(); MessageTrigger trigger = new MessageTrigger(); trigger.engine = engine; trigger.messageName = MESSAGE_NAME; trigger.activityId = startEventId; return trigger; }
public static BpmnModelInstance subProcessBpmnCallActivityProcess(String calledProcessKey) { return ProcessModels.newModel() .startEvent() .subProcess("subProcess") .embeddedSubProcess() .startEvent() .callActivity("callActivity") .calledElement(calledProcessKey) .userTask("userTask") .endEvent() .subProcessDone() .endEvent() .done(); }
@Test public void testNonInterruptingSetVariableOnInputMappingInSubProcessWithBoundary() { BpmnModelInstance modelInstance = Bpmn.createExecutableProcess(CONDITIONAL_EVENT_PROCESS_KEY) .startEvent() .subProcess(SUB_PROCESS_ID) .camundaInputParameter(VARIABLE_NAME, "1") .embeddedSubProcess() .startEvent() .userTask(TASK_WITH_CONDITION_ID) .name(TASK_WITH_CONDITION) .endEvent() .subProcessDone() .endEvent() .done(); modelInstance = addEventSubProcess(modelInstance, SUB_PROCESS_ID, TASK_AFTER_COND_START_EVENT_IN_SUB_PROCESS, false); deployMixedProcess(modelInstance, CONDITIONAL_EVENT_PROCESS_KEY, SUB_PROCESS_ID, false); // given ProcessInstance procInst = runtimeService.startProcessInstanceByKey(CONDITIONAL_EVENT_PROCESS_KEY); TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(procInst.getId()); //when input mapping sets variable //then conditional boundary event should triggered and also conditional start event in sub process //via the default evaluation behavior but not the global event sub process //since variable is only local tasksAfterVariableIsSet = taskQuery.list(); assertEquals(3, tasksAfterVariableIsSet.size()); assertTaskNames(tasksAfterVariableIsSet, TASK_AFTER_COND_START_EVENT_IN_SUB_PROCESS, TASK_AFTER_CONDITIONAL_BOUNDARY_EVENT, TASK_WITH_CONDITION); }
.startEvent() .subProcess(SUB_PROCESS_ID) .camundaExecutionListenerClass(ExecutionListener.EVENTNAME_END, SetVariableDelegate.class.getName()) .embeddedSubProcess() .startEvent() .userTask(USER_TASK_ID) .endEvent() .subProcessDone() .endEvent() .done()) .addSubProcessTo(PROC_DEF_KEY) .triggerByEvent() .embeddedSubProcess() .startEvent(EVENT_SUB_PROCESS_START_ID) .condition(VAR_CONDITION) .triggerByEvent() .embeddedSubProcess() .startEvent() .condition(VAR_CONDITION) .triggerByEvent() .embeddedSubProcess() .startEvent(EVENT_SUB_PROCESS_START_ID) .condition(VAR_CONDITION)