@Test @Cover( classes = {ErrorEventTriggerDefinition.class, BoundaryEventDefinition.class}, concept = BPMNConcept.EVENTS, keywords = {"error", "boundary", "event"}, jira = "ENGINE-501") public void uncaughtThrowErrorEvent() throws Exception { final ProcessDefinition calledProcDef = deployAndEnableProcessWithEndThrowErrorEvent("calledProcess", "error1"); // catch a different error final ProcessDefinition callerProcDef = deployAndEnableProcessWithBoundaryErrorEventOnCallActivity( "pErrorBoundary", "calledProcess", "callStep", "error2", "delivery"); final ProcessInstance processInstance = getProcessAPI().startProcess(callerProcDef.getId()); waitForFlowNodeInExecutingState(processInstance, "callStep", false); final long calledStep2Id = waitForUserTask(processInstance, "calledStep2"); waitForUserTaskAndExecuteIt(processInstance, "calledStep1", user); waitForArchivedActivity(calledStep2Id, TestStates.ABORTED); // if there are no catch error able to handle the thrown error, the throw error event has the // same behavior as a terminate event. waitForUserTaskAndExecuteIt(processInstance, "step2", user); waitForProcessToFinish(processInstance); checkWasntExecuted(processInstance, EXCEPTION_STEP); disableAndDeleteProcess(calledProcDef, callerProcDef); }
@Test @Cover( classes = { ErrorEventTriggerDefinition.class, BoundaryEventDefinition.class, MultiInstanceActivityInstance.class, CallActivityInstance.class }, concept = BPMNConcept.EVENTS, keywords = {"error", "boundary", "event", "call activity", "mutliple instance"}, jira = "ENGINE-9023") public void errorCodeThrownBySubProcessShouldBeCatchByMainProcess() throws Exception { final ProcessDefinition subProcess = deployAndEnableSubProcessWhichThrowsAnErrorEvent("SubProcess", "Mistake"); final ProcessDefinition midProcess = deployAndEnableMidProcessWhichContainsACallActivity("MidProcess", "SubProcess"); final ProcessDefinition mainProcess = deployAndEnableProcessWithBoundaryErrorEventOnMICallActivity( "Process", "MidProcess", "Mistake", "acme"); final ProcessInstance instance = getProcessAPI().startProcess(mainProcess.getId()); waitForFlowNodeInReadyState(instance, EXCEPTION_STEP, true); waitForFlowNodeInState(instance, "step1", TestStates.ABORTED, false); disableAndDeleteProcess(mainProcess, midProcess, subProcess); }
@Test @Cover( classes = {ErrorEventTriggerDefinition.class, BoundaryEventDefinition.class}, concept = BPMNConcept.EVENTS, keywords = {"error", "boundary", "event", "call activity"}, jira = "ENGINE-501") public void errorBoundaryEventNotTriggered() throws Exception { final ProcessDefinition calledProcDef = deployAndEnableProcessWithEndThrowErrorEvent("calledProcess", "error1"); final ProcessDefinition callerProcDef = deployAndEnableProcessWithBoundaryErrorEventOnCallActivity( "pErrorBoundary", "calledProcess", "callStep", "error1", "delivery"); try { final ProcessInstance processInstance = getProcessAPI().startProcess(callerProcDef.getId()); final ActivityInstance calledStep1 = waitForUserTaskAndGetIt(processInstance, "calledStep1"); final ProcessInstance calledProcessInstance = getProcessAPI().getProcessInstance(calledStep1.getParentProcessInstanceId()); waitForUserTaskAndExecuteIt(processInstance, "calledStep2", user); waitForFlowNodeInState(processInstance, "calledStep1", TestStates.ABORTED, true); waitForProcessToFinish(calledProcessInstance); waitForUserTaskAndExecuteIt(processInstance, "step2", user); waitForProcessToFinish(processInstance); checkWasntExecuted(processInstance, EXCEPTION_STEP); } finally { disableAndDeleteProcess(calledProcDef, callerProcDef); } }
@Test public void deletingProcessDeletesActorMappings() throws Exception { final TenantServiceAccessor tenantAccessor = getTenantAccessor(); final UserTransactionService transactionService = tenantAccessor.getUserTransactionService(); final String userTaskName = "actNaturally"; final ProcessDefinition definition = deployAndEnableProcessWithOneHumanTask( "deletingProcessDeletesActorMappings", "CandidateForOscarReward", userTaskName); final ProcessInstance processInstanceId = getProcessAPI().startProcess(definition.getId()); waitForUserTask(processInstanceId, userTaskName); disableAndDeleteProcess(definition); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved final List<SActorMember> actorMembers = transactionService.executeInTransaction( new Callable<List<SActorMember>>() { @Override public List<SActorMember> call() throws Exception { return getTenantAccessor() .getActorMappingService() .getActorMembersOfUser(john.getId(), 0, 1); } }); // Check there is no actor left: assertEquals(0, actorMembers.size()); }
/* * 1 receiveProcess, 1 sendProcess, Message contains datas goes from EndEvent to ReceiveTask * dynamic -> deployAndEnable(sendProcess), deployAndEnable(receiveProcess), startProcess(receiveProcess), startProcess(sendProcess) * checks : receiveProcess wait on receive task, sendProcess is finished, receiveProcess goes through receive task (found message sent by * sendProcess) and reaches user task, data is transmitted to * the receiveProcess. */ @Cover( classes = {EventInstance.class, ReceiveTaskInstance.class}, concept = BPMNConcept.EVENTS, keywords = {"Event", "Message event", "Receive task", "Send", "Receive"}, jira = "") @Test public void receiveMessageWithData() throws Exception { final ProcessDefinition sendMessageProcess = deployAndEnableProcessWithEndMessageEvent( "sendMessageProcess", "m5", "receiveMessageProcess", "waitForMessage", null, Collections.singletonMap("lastName", String.class.getName()), Collections.singletonMap("lName", String.class.getName()), Collections.singletonMap("lName", "lastName")); final List<Operation> receiveMessageOperations = Collections.singletonList( buildAssignOperation( "name", "lName", String.class.getName(), ExpressionType.TYPE_VARIABLE)); final ProcessDefinition receiveMessageProcess = deployAndEnableProcessWithReceivedTask( "receiveMessageProcess", "waitForMessage", "userTask1", "delivery", user, "m5", null, Collections.singletonMap("name", String.class.getName()), receiveMessageOperations); final ProcessInstance receiveMessageProcessInstance = getProcessAPI().startProcess(receiveMessageProcess.getId()); waitForFlowNodeInState( receiveMessageProcessInstance, "waitForMessage", TestStates.WAITING, true); final ProcessInstance sendMessageProcessInstance = getProcessAPI() .startProcess( sendMessageProcess.getId(), Arrays.asList( buildAssignOperation( "lastName", "Doe", String.class.getName(), ExpressionType.TYPE_CONSTANT)), null); waitForProcessToFinish(sendMessageProcessInstance); forceMatchingOfEvents(); final HumanTaskInstance step1 = waitForUserTaskAndGetIt(receiveMessageProcessInstance, "userTask1"); final DataInstance dataInstance = getProcessAPI().getProcessDataInstance("name", step1.getRootContainerId()); assertEquals("Doe", dataInstance.getValue()); disableAndDeleteProcess(sendMessageProcess); disableAndDeleteProcess(receiveMessageProcess); }
@Test public void checkMoreThan20DependenciesAreDeletedWhenProcessIsDeleted() throws Exception { final TenantServiceAccessor tenantAccessor = getTenantAccessor(); final DependencyService dependencyService = tenantAccessor.getDependencyService(); final UserTransactionService transactionService = tenantAccessor.getUserTransactionService(); final ProcessDefinitionBuilder processDef = new ProcessDefinitionBuilder().createNewInstance("processToTestTransitions", "1.0"); processDef.addStartEvent("start").addUserTask("step1", ACTOR_NAME).addEndEvent("end"); processDef.addTransition("start", "step1").addTransition("step1", "end"); processDef.addActor(ACTOR_NAME); final BusinessArchiveBuilder businessArchiveBuilder = new BusinessArchiveBuilder() .createNewBusinessArchive() .setProcessDefinition(processDef.done()); for (int i = 0; i < 25; i++) { final byte[] content = new byte[] { 1, 2, 3, 4, 5, 6, 7, (byte) (i >>> 24), (byte) (i >> 16 & 0xff), (byte) (i >> 8 & 0xff), (byte) (i & 0xff) }; businessArchiveBuilder.addClasspathResource(new BarResource("myDep" + i, content)); } final ProcessDefinition definition = deployAndEnableProcessWithActor(businessArchiveBuilder.done(), ACTOR_NAME, john); final ProcessInstance processInstance = getProcessAPI().startProcess(definition.getId()); final Long step1Id = waitForUserTask(processInstance, "step1"); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved List<Long> dependencyIds = transactionService.executeInTransaction( new GetDependenciesIds(getSession(), definition.getId(), dependencyService, 0, 100)); assertEquals(25, dependencyIds.size()); final SDependency dependency = transactionService.executeInTransaction( new GetSDependency(dependencyIds.get(0), dependencyService)); assertNotNull(dependency); assignAndExecuteStep(step1Id, john.getId()); waitForProcessToFinish(processInstance); disableAndDeleteProcess(definition); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved dependencyIds = transactionService.executeInTransaction( new GetDependenciesIds(getSession(), definition.getId(), dependencyService, 0, 100)); assertEquals(0, dependencyIds.size()); }
private ProcessDefinition deployAndEnableProcessWithReceivedTask( final String processName, final String receiveTaskName, final String userTaskName, final String actorName, final User user, final String messageName, final List<BEntry<Expression, Expression>> correlations, final Map<String, String> processData, final List<Operation> operations) throws BonitaException { final ProcessDefinitionBuilder processBuilder = new ProcessDefinitionBuilder(); processBuilder.createNewInstance(processName, "1.0"); addProcessData(processData, processBuilder); processBuilder.addStartEvent("startEvent"); final ReceiveTaskDefinitionBuilder receiveTaskBuilder = processBuilder.addReceiveTask(receiveTaskName, messageName); if (correlations != null) { for (final Entry<Expression, Expression> entry : correlations) { receiveTaskBuilder.addCorrelation(entry.getKey(), entry.getValue()); } } if (operations != null) { for (final Operation operation : operations) { receiveTaskBuilder.addMessageOperation(operation); } } processBuilder.addActor(actorName); processBuilder.addUserTask(userTaskName, actorName); processBuilder.addEndEvent("endEvent"); processBuilder.addTransition("startEvent", receiveTaskName); processBuilder.addTransition(receiveTaskName, userTaskName); processBuilder.addTransition(userTaskName, "endEvent"); final DesignProcessDefinition designProcessDefinition = processBuilder.done(); final BusinessArchiveBuilder archiveBuilder = new BusinessArchiveBuilder(); archiveBuilder.createNewBusinessArchive().setProcessDefinition(designProcessDefinition); final BusinessArchive receiveMessaceArchive = archiveBuilder.done(); final ProcessDefinition receiveMessageProcess = deployProcess(receiveMessaceArchive); final List<ActorInstance> actors = getProcessAPI().getActors(receiveMessageProcess.getId(), 0, 1, ActorCriterion.NAME_ASC); getProcessAPI().addUserToActor(actors.get(0).getId(), user.getId()); getProcessAPI().enableProcess(receiveMessageProcess.getId()); final ProcessDeploymentInfo processDeploymentInfo = getProcessAPI().getProcessDeploymentInfo(receiveMessageProcess.getId()); assertEquals(ActivationState.ENABLED, processDeploymentInfo.getActivationState()); return receiveMessageProcess; }
@Test @Cover( classes = {ErrorEventTriggerDefinition.class, BoundaryEventDefinition.class}, concept = BPMNConcept.EVENTS, keywords = {"error", "boundary", "event"}, jira = "ENGINE-501") public void errorEventTwoCatchErrorMatching() throws Exception { final ProcessDefinition procDefLevel0 = deployAndEnableProcessWithEndThrowErrorEvent("procDefLevel0", "error1"); final ProcessDefinition procDefLevel1 = deployAndEnableProcessWithBoundaryErrorEventOnCallActivity( "procDefLevel1", "procDefLevel0", "callStepL1", "error1", "delivery"); final ProcessDefinition procDefLevel2 = deployAndEnableProcessWithBoundaryErrorEventOnCallActivity( "procDefLevel2", "procDefLevel1", "callStepL2", "error1", "delivery"); final ProcessInstance processInstance = getProcessAPI().startProcess(procDefLevel2.getId()); final FlowNodeInstance callActivityL2 = waitForFlowNodeInExecutingState(processInstance, "callStepL2", false); final FlowNodeInstance callActivityL1 = waitForFlowNodeInExecutingState(processInstance, "callStepL1", true); final ActivityInstance calledStep1 = waitForUserTaskAndGetIt(processInstance, "calledStep1"); final long calledStep2Id = waitForUserTask(processInstance, "calledStep2"); final ProcessInstance calledProcessInstanceL0 = getProcessAPI().getProcessInstance(calledStep1.getParentProcessInstanceId()); final ProcessInstance calledProcessInstanceL1 = getProcessAPI().getProcessInstance(callActivityL1.getParentProcessInstanceId()); assignAndExecuteStep(calledStep1, user.getId()); waitForArchivedActivity(calledStep2Id, TestStates.ABORTED); final FlowNodeInstance executionStep = waitForFlowNodeInReadyState(calledProcessInstanceL1, EXCEPTION_STEP, false); waitForProcessToFinish(calledProcessInstanceL0); assignAndExecuteStep(executionStep.getId(), user.getId()); waitForProcessToFinish(calledProcessInstanceL1); waitForUserTaskAndExecuteIt(processInstance, "step2", user); waitForProcessToFinish(processInstance); waitForArchivedActivity(callActivityL1.getId(), TestStates.ABORTED); waitForArchivedActivity(callActivityL2.getId(), TestStates.NORMAL_FINAL); checkWasntExecuted(calledProcessInstanceL1, "step2"); disableAndDeleteProcess(procDefLevel0, procDefLevel1, procDefLevel2); }
@Test public void checkPendingMappingAreDeleted() throws Exception { final TenantServiceAccessor tenantAccessor = getTenantAccessor(); final ActivityInstanceService activityInstanceService = tenantAccessor.getActivityInstanceService(); final UserTransactionService transactionService = tenantAccessor.getUserTransactionService(); final ProcessDefinitionBuilder processDef = new ProcessDefinitionBuilder().createNewInstance("processToTestComment", "1.0"); processDef.addShortTextData( "kikoo", new ExpressionBuilder().createConstantStringExpression("lol")); processDef.addStartEvent("start"); processDef .addUserTask("step1", ACTOR_NAME) .addShortTextData("kikoo2", new ExpressionBuilder().createConstantStringExpression("lol")); processDef.addUserTask("step2", ACTOR_NAME); processDef.addEndEvent("end"); processDef.addTransition("start", "step1"); processDef.addTransition("step1", "step2"); processDef.addTransition("step2", "end"); processDef.addActor(ACTOR_NAME); final ProcessDefinition definition = deployAndEnableProcessWithActor(processDef.done(), ACTOR_NAME, john); final ProcessInstance processInstance = getProcessAPI().startProcess(definition.getId()); final Long step1Id = waitForUserTask(processInstance, "step1"); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved final Callable<List<SPendingActivityMapping>> getPendingMappings = new Callable<List<SPendingActivityMapping>>() { @Override public List<SPendingActivityMapping> call() throws Exception { final QueryOptions queryOptions = new QueryOptions(0, 100, SPendingActivityMapping.class, "id", OrderByType.ASC); return activityInstanceService.getPendingMappings(step1Id, queryOptions); } }; List<SPendingActivityMapping> mappings = transactionService.executeInTransaction(getPendingMappings); assertEquals(1, mappings.size()); assignAndExecuteStep(step1Id, john.getId()); waitForUserTask(processInstance, "step2"); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved mappings = transactionService.executeInTransaction(getPendingMappings); assertEquals(0, mappings.size()); disableAndDeleteProcess(definition); }
protected void executionWitherrorEventTriggered(final String catchErrorCode) throws Exception { final ProcessDefinition calledProcDef = deployAndEnableProcessWithEndThrowErrorEvent("calledProcess", "error1"); final ProcessDefinition callerProcDef = deployAndEnableProcessWithBoundaryErrorEventOnCallActivity( "pErrorBoundary", "calledProcess", "callStep", catchErrorCode, "delivery"); final ProcessInstance processInstance = getProcessAPI().startProcess(callerProcDef.getId()); final FlowNodeInstance callActivity = waitForFlowNodeInExecutingState(processInstance, "callStep", false); final ActivityInstance calledStep1 = waitForUserTaskAndGetIt(processInstance, "calledStep1"); final long calledStep2Id = waitForUserTask(processInstance, "calledStep2"); final ProcessInstance calledProcessInstance = getProcessAPI().getProcessInstance(calledStep1.getParentProcessInstanceId()); assignAndExecuteStep(calledStep1, user); waitForProcessToFinish(calledProcessInstance); try { waitForArchivedActivity(calledStep2Id, TestStates.ABORTED); } catch (final Exception e) { final List<ArchivedActivityInstance> archivedActivityInstances = getProcessAPI() .getArchivedActivityInstances( processInstance.getId(), 0, 100, ActivityInstanceCriterion.DEFAULT); System.out.println("After completion of the called process"); for (final ArchivedActivityInstance archivedActivityInstance : archivedActivityInstances) { System.out.println( "name=" + archivedActivityInstance.getName() + ", state=" + archivedActivityInstance.getState() + ", archivedDate=" + archivedActivityInstance.getArchiveDate().getTime()); } throw new Exception(archivedActivityInstances.toString(), e); } waitForUserTaskAndExecuteIt(processInstance, EXCEPTION_STEP, user); waitForProcessToFinish(processInstance); waitForArchivedActivity(callActivity.getId(), TestStates.ABORTED); checkWasntExecuted(processInstance, "step2"); disableAndDeleteProcess(calledProcDef, callerProcDef); }
@Test public void checkDependenciesAreDeletedWhenProcessIsDeleted() throws Exception { final TenantServiceAccessor tenantAccessor = getTenantAccessor(); final DependencyService dependencyService = tenantAccessor.getDependencyService(); final UserTransactionService transactionService = tenantAccessor.getUserTransactionService(); final ProcessDefinitionBuilder processDef = new ProcessDefinitionBuilder().createNewInstance("processToTestTransitions", "1.0"); processDef.addStartEvent("start"); processDef.addUserTask("step1", ACTOR_NAME); processDef.addEndEvent("end"); processDef.addTransition("start", "step1"); processDef.addTransition("step1", "end"); processDef.addActor(ACTOR_NAME); final byte[] content = new byte[] {1, 2, 3, 4, 5, 6, 7}; final BusinessArchive businessArchive = new BusinessArchiveBuilder() .createNewBusinessArchive() .setProcessDefinition(processDef.done()) .addClasspathResource(new BarResource("myDep", content)) .done(); final ProcessDefinition definition = deployAndEnableProcessWithActor(businessArchive, ACTOR_NAME, john); final ProcessInstance processInstance = getProcessAPI().startProcess(definition.getId()); final Long step1Id = waitForUserTask(processInstance, "step1"); List<Long> dependencyIds = transactionService.executeInTransaction( new GetDependenciesIds(getSession(), definition.getId(), dependencyService, 0, 100)); assertEquals(1, dependencyIds.size()); final SDependency dependency = transactionService.executeInTransaction( new GetSDependency(dependencyIds.get(0), dependencyService)); assertTrue(dependency.getName().endsWith("myDep")); assertTrue(Arrays.equals(content, dependency.getValue())); assignAndExecuteStep(step1Id, john); waitForProcessToFinish(processInstance); disableAndDeleteProcess(definition); dependencyIds = transactionService.executeInTransaction( new GetDependenciesIds(getSession(), definition.getId(), dependencyService, 0, 100)); assertEquals(0, dependencyIds.size()); }
/* * 1 receiveProcess, no message sent * dynamic -> deployAndEnable(receiveProcess), startProcess(receiveProcess) * checks : receiveProcess wait on receive task and don't and halt on the user task. */ @SuppressWarnings("unchecked") @Cover( classes = {EventInstance.class, ReceiveTaskInstance.class}, concept = BPMNConcept.EVENTS, keywords = {"Event", "Message event", "Receive task", "Send", "Receive"}, jira = "") @Test public void noMessageSentSoReceiveProcessIsWaiting() throws Exception { final ProcessDefinition receiveMessageProcess = deployAndEnableProcessWithReceivedTask( "receiveMessageProcess", "waitForMessage", "userTask1", "delivery", user, "m1", null, null, null); final ProcessInstance receiveMessageProcessInstance = getProcessAPI().startProcess(receiveMessageProcess.getId()); waitForFlowNodeInState( receiveMessageProcessInstance, "waitForMessage", TestStates.WAITING, true); // we check after that that the waiting event is still here forceMatchingOfEvents(); final SearchOptionsBuilder searchOptionsBuilder = new SearchOptionsBuilder(0, 10); searchOptionsBuilder.filter( WaitingEventSearchDescriptor.ROOT_PROCESS_INSTANCE_ID, receiveMessageProcessInstance.getId()); final Map<String, Serializable> parameters = new HashMap<String, Serializable>(1); parameters.put(SEARCH_OPTIONS_KEY, searchOptionsBuilder.done()); final SearchResult<WaitingEvent> searchResult = (SearchResult<WaitingEvent>) getCommandAPI().execute(SEARCH_WAITING_EVENTS_COMMAND, parameters); assertEquals(1, searchResult.getCount()); disableAndDeleteProcess(receiveMessageProcess); }
/* * Verify receiveProcess receive message targeting it, even if sent before its existence. * 1 receiveProcess, 1 sendProcess, Message goes from EndEvent to ReceiveTask * dynamic -> deployAndEnable(sendProcess), startProcess(sendProcess), deployAndEnable(receiveProcess), startProcess(receiveProcess) * checks : sendProcess is finished, receiveProcess goes through receive task (found message sent by sendProcess) and reaches user task. */ @Cover( classes = {EventInstance.class, ReceiveTaskInstance.class}, concept = BPMNConcept.EVENTS, keywords = {"Event", "Message event", "Receive task", "Send", "Receive"}, jira = "") @Test public void receiveMessageSentBeforeReceiveProcessIsEnabled() throws Exception { final ProcessDefinition sendMessageProcess = deployAndEnableProcessWithEndMessageEvent( "sendMessageProcess", "m3", "receiveMessageProcess", "waitForMessage", null, null, null, null); final ProcessInstance sendMessageProcessInstance = getProcessAPI().startProcess(sendMessageProcess.getId()); waitForProcessToFinish(sendMessageProcessInstance); final ProcessDefinition receiveMessageProcess = deployAndEnableProcessWithReceivedTask( "receiveMessageProcess", "waitForMessage", "userTask1", "delivery", user, "m3", null, null, null); final ProcessInstance receiveMessageProcessInstance = getProcessAPI().startProcess(receiveMessageProcess.getId()); forceMatchingOfEvents(); waitForUserTask(receiveMessageProcessInstance, "userTask1"); disableAndDeleteProcess(sendMessageProcess); disableAndDeleteProcess(receiveMessageProcess); }
@Cover( jira = "BS-9484", classes = {MultiInstanceActivityInstance.class}, concept = BPMNConcept.EVENTS, keywords = {"error event", "multi instance"}) @Test public void processWithMIUserTaskWithErrorEvent_should_take_the_error_flow() throws Exception { final ProcessDefinitionBuilder processDefinitionBuilder = BuildTestUtil.buildProcessDefinitionWithMultiInstanceUserTaskAndFailedConnector( PROCESS_NAME, "step1"); final ProcessDefinition processDefinition = deployAndEnableProcessWithTestConnectorThatThrowException(processDefinitionBuilder); final ProcessInstance processInstance = getProcessAPI().startProcess(processDefinition.getId()); waitForUserTaskAndExecuteIt(processInstance, "step1", user); waitForUserTaskAndExecuteIt(processInstance, "errorFlow", user); waitForProcessToFinish(processInstance); disableAndDeleteProcess(processDefinition.getId()); }
private ProcessDefinition deployAndEnableProcessWithEndMessageEvent( final String processName, final String messageName, final String targetProcess, final String targetFlowNode, final List<BEntry<Expression, Expression>> correlations, final Map<String, String> processData, final Map<String, String> messageData, final Map<String, String> dataInputMapping) throws BonitaException { final ProcessDefinitionBuilder processBuilder = new ProcessDefinitionBuilder(); processBuilder.createNewInstance(processName, "1.0"); addProcessData(processData, processBuilder); processBuilder.addStartEvent("startEvent"); processBuilder.addAutomaticTask("auto1"); // create expression for target process/flowNode final Expression targetProcessExpression = new ExpressionBuilder().createConstantStringExpression(targetProcess); final Expression targetFlowNodeExpression = new ExpressionBuilder().createConstantStringExpression(targetFlowNode); final ThrowMessageEventTriggerBuilder throwMessageEventTriggerBuilder = processBuilder .addEndEvent("endEvent") .addMessageEventTrigger(messageName, targetProcessExpression, targetFlowNodeExpression); addCorrelations(correlations, throwMessageEventTriggerBuilder); addMessageData(messageData, dataInputMapping, throwMessageEventTriggerBuilder); processBuilder.addTransition("startEvent", "auto1"); processBuilder.addTransition("auto1", "endEvent"); final DesignProcessDefinition designProcessDefinition = processBuilder.done(); final ProcessDefinition sendMessageProcess = deployAndEnableProcess(designProcessDefinition); final ProcessDeploymentInfo processDeploymentInfo = getProcessAPI().getProcessDeploymentInfo(sendMessageProcess.getId()); assertEquals(ActivationState.ENABLED, processDeploymentInfo.getActivationState()); return sendMessageProcess; }
private static String getProcessFormName(long processDefinitionId, ProcessAPI processAPI) throws ProcessDefinitionNotFoundException { ProcessDefinition processDefinition = processAPI.getProcessDefinition(processDefinitionId); return processDefinition.getName() + "--" + processDefinition.getVersion(); }
@Test public void checkProcessCommentAreArchived() throws Exception { final TenantServiceAccessor tenantAccessor = getTenantAccessor(); final SCommentService commentService = tenantAccessor.getCommentService(); final UserTransactionService transactionService = tenantAccessor.getUserTransactionService(); final ProcessDefinitionBuilder processDef = new ProcessDefinitionBuilder().createNewInstance("processToTestComment", "1.0"); processDef.addStartEvent("start"); processDef.addUserTask("step1", ACTOR_NAME); processDef.addEndEvent("end"); processDef.addTransition("start", "step1"); processDef.addTransition("step1", "end"); processDef.addActor(ACTOR_NAME); final ProcessDefinition definition = deployAndEnableProcessWithActor(processDef.done(), ACTOR_NAME, john); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved final Callable<Long> getNumberOfComments = new Callable<Long>() { @Override public Long call() throws Exception { return commentService.getNumberOfComments(QueryOptions.countQueryOptions()); } }; final Callable<Long> getNumberOfArchivedComments = new Callable<Long>() { @Override public Long call() throws Exception { return commentService.getNumberOfArchivedComments(QueryOptions.countQueryOptions()); } }; assertEquals(0, (long) transactionService.executeInTransaction(getNumberOfComments)); final long numberOfInitialArchivedComments = transactionService.executeInTransaction(getNumberOfArchivedComments); final ProcessInstance processInstance = getProcessAPI().startProcess(definition.getId()); final Long step1Id = waitForUserTask(processInstance, "step1"); getProcessAPI().addProcessComment(processInstance.getId(), "kikoo lol"); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved assertEquals(1, (long) transactionService.executeInTransaction(getNumberOfComments)); assertEquals( numberOfInitialArchivedComments, (long) transactionService.executeInTransaction(getNumberOfArchivedComments)); assignAndExecuteStep(step1Id, john); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved assertEquals( 2, (long) transactionService.executeInTransaction(getNumberOfComments)); // claim add a comment... assertEquals( numberOfInitialArchivedComments, (long) transactionService.executeInTransaction(getNumberOfArchivedComments)); waitForProcessToFinish(processInstance); setSessionInfo(getSession()); // the session was cleaned by api call. This must be improved assertEquals(0, (long) transactionService.executeInTransaction(getNumberOfComments)); assertEquals( numberOfInitialArchivedComments + 2, (long) transactionService.executeInTransaction(getNumberOfArchivedComments)); disableAndDeleteProcess(definition); }
/* * dynamic -> deployAndEnable(receiveProcess), startProcess(receiveProcess), cancelProcessInstance(receiveProcess) * checks : receiveProcess wait on receive task, 1 waiting event, receiveProcess is cancelled, receiveProcess is archived, no more waiting event */ @SuppressWarnings("unchecked") @Cover( classes = {EventInstance.class, ReceiveTaskInstance.class}, concept = BPMNConcept.EVENTS, keywords = {"Event", "Message event", "Receive task", "Send", "Receive"}, jira = "") @Test public void cancelInstanceShouldDeleteWaitingEvents() throws Exception { final ProcessDefinition receiveMessageProcess = deployAndEnableProcessWithReceivedTask( "receiveMessageProcess", "waitForMessage", "userTask1", "delivery", user, "m1", null, null, null); final ProcessInstance receiveMessageProcessInstance = getProcessAPI().startProcess(receiveMessageProcess.getId()); waitForFlowNodeInState( receiveMessageProcessInstance, "waitForMessage", TestStates.WAITING, true); SearchOptionsBuilder searchOptionsBuilder = new SearchOptionsBuilder(0, 10); searchOptionsBuilder.filter( WaitingEventSearchDescriptor.ROOT_PROCESS_INSTANCE_ID, receiveMessageProcessInstance.getId()); final Map<String, Serializable> parameters = new HashMap<String, Serializable>(1); parameters.put(SEARCH_OPTIONS_KEY, searchOptionsBuilder.done()); SearchResult<WaitingEvent> searchResult = (SearchResult<WaitingEvent>) getCommandAPI().execute(SEARCH_WAITING_EVENTS_COMMAND, parameters); assertEquals(1, searchResult.getCount()); getProcessAPI().cancelProcessInstance(receiveMessageProcessInstance.getId()); waitForProcessToBeInState(receiveMessageProcessInstance, ProcessInstanceState.CANCELLED); searchOptionsBuilder = new SearchOptionsBuilder(0, 10); searchOptionsBuilder.filter( ArchivedActivityInstanceSearchDescriptor.ROOT_PROCESS_INSTANCE_ID, receiveMessageProcessInstance.getId()); searchOptionsBuilder.filter( ArchivedActivityInstanceSearchDescriptor.ACTIVITY_TYPE, FlowNodeType.RECEIVE_TASK); final SearchResult<ArchivedActivityInstance> archivedActivityInstancesSearch = getProcessAPI().searchArchivedActivities(searchOptionsBuilder.done()); assertEquals(1, archivedActivityInstancesSearch.getCount()); assertTrue( archivedActivityInstancesSearch.getResult().get(0) instanceof ArchivedReceiveTaskInstance); assertEquals( TestStates.CANCELLED.getStateName(), archivedActivityInstancesSearch.getResult().get(0).getState()); searchResult = (SearchResult<WaitingEvent>) getCommandAPI().execute(SEARCH_WAITING_EVENTS_COMMAND, parameters); assertEquals(0, searchResult.getCount()); disableAndDeleteProcess(receiveMessageProcess); }
@Test @Cover( classes = {}, concept = BPMNConcept.ACTIVITIES, jira = "ENGINE-469", keywords = {"node", "restart", "transition", "flownode"}, story = "elements must be restarted when they were not completed when the node was shut down") public void restartHandlerTests() throws Exception { /* * process with blocking connector */ final ProcessDefinitionBuilder builder1 = new ProcessDefinitionBuilder().createNewInstance("p1", "1.0"); builder1.addActor(ACTOR_NAME); builder1.addUserTask("step1", ACTOR_NAME); builder1 .addAutomaticTask("step2") .addConnector("myConnector", "blocking-connector", "1.0", ConnectorEvent.ON_ENTER); builder1.addTransition("step1", "step2"); builder1.addUserTask("ustep2", ACTOR_NAME); builder1.addTransition("step2", "ustep2"); final BusinessArchive businessArchive = new BusinessArchiveBuilder() .createNewBusinessArchive() .setProcessDefinition(builder1.done()) .addConnectorImplementation( new BarResource( "blocking-connector.impl", BuildTestUtil.buildConnectorImplementationFile( "blocking-connector", "1.0", "blocking-connector-impl", "1.0", BlockingConnector.class.getName()))) .done(); final ProcessDefinition p1 = deployAndEnableProcessWithActor(businessArchive, ACTOR_NAME, john); /* * process with blocking operation (executing work) */ final ProcessDefinitionBuilder builder2 = new ProcessDefinitionBuilder().createNewInstance("p2", "1.0"); final String blockingGroovyScript1 = "org.bonitasoft.engine.test.BPMLocalIT.tryAcquireSemaphore1();\nreturn \"done\";"; builder2.addActor(ACTOR_NAME); builder2.addShortTextData("data", null); builder2.addUserTask("step1", ACTOR_NAME); builder2 .addAutomaticTask("step2") .addOperation( new OperationBuilder() .createSetDataOperation( "data", new ExpressionBuilder() .createGroovyScriptExpression( "blockingGroovyScript1", blockingGroovyScript1, String.class.getName()))); builder2.addTransition("step1", "step2"); builder2.addUserTask("ustep2", ACTOR_NAME); builder2.addTransition("step2", "ustep2"); final ProcessDefinition p2 = deployAndEnableProcessWithActor(builder2.done(), ACTOR_NAME, john); /* * process with blocking transition (notify work) */ final ProcessDefinitionBuilder builder3 = new ProcessDefinitionBuilder().createNewInstance("p3", "1.0"); final String blockingGroovyScript2 = "org.bonitasoft.engine.test.BPMLocalIT.tryAcquireSemaphore2();\nreturn true;"; builder3.addActor(ACTOR_NAME); builder3.addUserTask("step1", ACTOR_NAME); builder3.addAutomaticTask("step2"); builder3.addTransition( "step1", "step2", new ExpressionBuilder() .createGroovyScriptExpression( "blockingGroovyScript2", blockingGroovyScript2, Boolean.class.getName())); builder3.addUserTask("ustep2", ACTOR_NAME); builder3.addTransition("step2", "ustep2"); final ProcessDefinition p3 = deployAndEnableProcessWithActor(builder3.done(), ACTOR_NAME, john); // Block all 3 tasks BlockingConnector.semaphore.acquire(); semaphore1.acquire(); semaphore2.acquire(); System.out.println("Start the process"); final ProcessInstance pi1 = getProcessAPI().startProcess(p1.getId()); final ProcessInstance pi2 = getProcessAPI().startProcess(p2.getId()); final ProcessInstance pi3 = getProcessAPI().startProcess(p3.getId()); waitForUserTaskAndExecuteIt(pi1, "step1", john); waitForUserTaskAndExecuteIt(pi2, "step1", john); waitForUserTaskAndExecuteIt(pi3, "step1", john); System.out.println("executed step1"); logoutOnTenant(); final PlatformSession loginPlatform = loginOnPlatform(); final PlatformAPI platformAPI = PlatformAPIAccessor.getPlatformAPI(loginPlatform); // stop node and in the same time release the semaphores to unlock works final Thread thread = new Thread( new Runnable() { @Override public void run() { try { Thread.sleep(200); } catch (final InterruptedException e) { e.printStackTrace(); } System.out.println("release semaphores"); BlockingConnector.semaphore.release(); semaphore1.release(); semaphore2.release(); System.out.println("released semaphores"); } }); System.out.println("stop node"); thread.start(); platformAPI.stopNode(); System.out.println("node stopped"); // release them (work will fail, node is stopped) thread.join(1000); Thread.sleep(50); System.out.println("start node"); platformAPI.startNode(); System.out.println("node started"); logoutOnPlatform(loginPlatform); loginOnDefaultTenantWithDefaultTechnicalUser(); // during stop node some flow node can be put in failed state retryFailedFlowNodes(); // check we have all task ready waitForPendingTasks(john.getId(), 3); disableAndDeleteProcess(p1.getId()); disableAndDeleteProcess(p2.getId()); disableAndDeleteProcess(p3.getId()); }
/* * 1 receiveProcess, 2 sendProcess, 2 Messages go from EndEvent to ReceiveTask * dynamic -> deployAndEnable(sendProcesses), startProcess(sendProcesses), deployAndEnable(receiveProcess), startProcess(receiveProcess) * checks : sendProcesses are finished, receiveProcess goes through receive task (found one message sent by sendProcess) and reaches user task. */ @Cover( classes = {EventInstance.class, ReceiveTaskInstance.class}, concept = BPMNConcept.EVENTS, keywords = {"Event", "Message event", "Receive task", "Send", "Receive"}, jira = "") @Test public void receiveMessageSentTwice() throws Exception { ProcessDefinition sendMessageProcess1 = null; ProcessDefinition sendMessageProcess2 = null; ProcessDefinition receiveMessageProcess = null; try { sendMessageProcess1 = deployAndEnableProcessWithEndMessageEvent( "sendMessageProcess1", "m4", "receiveMessageProcess", "waitForMessage", null, null, null, null); sendMessageProcess2 = deployAndEnableProcessWithEndMessageEvent( "sendMessageProcess2", "m4", "receiveMessageProcess", "waitForMessage", null, null, null, null); final ProcessInstance sendMessageProcessInstance1 = getProcessAPI().startProcess(sendMessageProcess1.getId()); final ProcessInstance sendMessageProcessInstance2 = getProcessAPI().startProcess(sendMessageProcess2.getId()); waitForProcessToFinish(sendMessageProcessInstance1); waitForProcessToFinish(sendMessageProcessInstance2); receiveMessageProcess = deployAndEnableProcessWithReceivedTask( "receiveMessageProcess", "waitForMessage", "userTask1", "delivery", user, "m4", null, null, null); final ProcessInstance receiveMessageProcessInstance = getProcessAPI().startProcess(receiveMessageProcess.getId()); waitForTaskInState(receiveMessageProcessInstance, "waitForMessage", TestStates.WAITING); forceMatchingOfEvents(); waitForUserTask(receiveMessageProcessInstance, "userTask1"); final ProcessInstance receiveMessageProcessInstance2 = getProcessAPI().startProcess(receiveMessageProcess.getId()); waitForTaskInState(receiveMessageProcessInstance2, "waitForMessage", TestStates.WAITING); forceMatchingOfEvents(); waitForUserTask(receiveMessageProcessInstance2, "userTask1"); } finally { disableAndDeleteProcess(sendMessageProcess1); disableAndDeleteProcess(sendMessageProcess2); disableAndDeleteProcess(receiveMessageProcess); } }
@Test @Cover( classes = CommandAPI.class, concept = BPMNConcept.ACTIVITIES, keywords = {"Command", "Updated variable value", "Activity instance"}, story = "Get updated variable values for activity instance.", jira = "") public void getUpdatedVariableValuesForActivity() throws Exception { final User user = createUser("toto", "titi"); // create process definition: final String dataName1 = "data1"; final String dataName2 = "data2"; final int dataValue = 1; final String actorName = "actor"; // Process Def level default data values are: data1=1, data2=1 final UserTaskDefinitionBuilder taskDefBuilder = new ProcessDefinitionBuilder() .createNewInstance("My_Process", "1.0") .addActor(actorName) .addIntegerData( dataName1, new ExpressionBuilder().createConstantIntegerExpression(dataValue)) .addIntegerData( dataName2, new ExpressionBuilder().createConstantIntegerExpression(dataValue)) .addUserTask("step1", actorName); // a data in step1 with same name 'data1' is also defined with value 11: taskDefBuilder.addIntegerData( dataName1, new ExpressionBuilder().createConstantIntegerExpression(11)); final DesignProcessDefinition processDef = taskDefBuilder.addUserTask("step2", actorName).addTransition("step1", "step2").getProcess(); final ProcessDefinition processDefinition = deployAndEnableWithActor(processDef, actorName, user); final long processDefinitionId = processDefinition.getId(); final ProcessInstance pi = getProcessAPI().startProcess(processDefinitionId); final WaitForStep waitForStep = waitForStep("step1", pi); final long activityInstanceId = waitForStep.getStepId(); // Let's update the value of data1 to 22. It should not be taken into account at process def // level: getProcessAPI().updateActivityDataInstance(dataName1, activityInstanceId, 22); // create current variable Name&Value map: var1 = 12, var2 = ArrayList{"a", "b"} final String varName1 = "var1"; final String varName2 = "var2"; final ArrayList<String> var2Value = new ArrayList<String>(); var2Value.add("a"); var2Value.add("b"); final Map<String, Serializable> currentVariables = new HashMap<String, Serializable>(); currentVariables.put(varName1, 12); currentVariables.put(varName2, var2Value); // Create Operation keyed map: final List<Operation> operations = new ArrayList<Operation>(); // First one is 'var1 = data1 + 33' final Expression dependencyData1 = new ExpressionBuilder().createDataExpression(dataName1, Integer.class.getName()); final Expression expression1 = new ExpressionBuilder() .createNewInstance("data1 + 33") .setContent("data1 + 33") .setDependencies(Arrays.asList(dependencyData1)) .setExpressionType(ExpressionType.TYPE_READ_ONLY_SCRIPT.name()) .setInterpreter("GROOVY") .setReturnType(Integer.class.getName()) .done(); final Operation integerOperation1 = new OperationBuilder() .createNewInstance() .setLeftOperand( new LeftOperandBuilder() .createNewInstance() .setName(varName1) .setExternal(true) .done()) .setType(OperatorType.ASSIGNMENT) .setOperator("=") .setRightOperand(expression1) .done(); final Map<String, Serializable> contexts = new HashMap<String, Serializable>(); operations.add(integerOperation1); // Second one is 'var2.add("toto" + data1)' final Expression dependencyToto = new ExpressionBuilder().createConstantStringExpression("\"toto\""); final Expression expression2 = new ExpressionBuilder() .createNewInstance("concat 'toto' to data1 value") .setContent("\"toto\" + data1") .setDependencies(Arrays.asList(dependencyToto, dependencyData1)) .setExpressionType(ExpressionType.TYPE_READ_ONLY_SCRIPT.name()) .setInterpreter("GROOVY") .setReturnType(String.class.getName()) .done(); final LeftOperand leftOperand = new LeftOperandBuilder().createNewInstance().setName(varName2).setExternal(true).done(); final Operation integerOperation2 = new OperationBuilder() .createNewInstance() .setOperator("add") .setOperatorInputType(Object.class.getName()) .setLeftOperand(leftOperand) .setType(OperatorType.JAVA_METHOD) .setRightOperand(expression2) .done(); operations.add(integerOperation2); // execute command: final String commandName = "getUpdatedVariableValuesForActivityInstance"; final HashMap<String, Serializable> commandParameters = new HashMap<String, Serializable>(); commandParameters.put("OPERATIONS_LIST_KEY", (Serializable) operations); commandParameters.put("OPERATIONS_INPUT_KEY", (Serializable) contexts); commandParameters.put("CURRENT_VARIABLE_VALUES_MAP_KEY", (Serializable) currentVariables); commandParameters.put("ACTIVITY_INSTANCE_ID_KEY", activityInstanceId); @SuppressWarnings("unchecked") final Map<String, Serializable> updatedVariable = (Map<String, Serializable>) getCommandAPI().execute(commandName, commandParameters); // check and do assert: assertTrue(updatedVariable.size() == 2); assertEquals(55, updatedVariable.get(varName1)); @SuppressWarnings("unchecked") final ArrayList<String> result = (ArrayList<String>) updatedVariable.get(varName2); assertEquals(3, result.size()); assertEquals("toto22", result.get(2)); disableAndDeleteProcess(processDefinition); deleteUser(user); }