未验证 提交 043b7ed4 编写于 作者: S salaboy 提交者: GitHub

Merge pull request #2331 from Activiti/2283-conformance-set3-4

2283 conformance set 3 and 4
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-conformance-tests</artifactId>
<version>7.0.0-SNAPSHOT</version>
</parent>
<artifactId>activiti-spring-conformance-set3</artifactId>
<packaging>jar</packaging>
<name>Activiti Spring :: Conformance Set 3</name>
<description>Activiti Spring :: Conformance Set 3</description>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-conformance-util</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-process-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-task-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-runtime-shared</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-task-model</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-process-model</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-model-shared</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package org.activiti.spring.conformance.set3;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
package org.activiti.spring.conformance.set3;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessDefinitionMeta;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.process.runtime.conf.ProcessRuntimeConfiguration;
import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
import org.activiti.api.runtime.shared.events.VariableEventListener;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class ConformanceBasicProcessRuntimeTest {
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private SecurityUtil securityUtil;
@Test
public void shouldGetConfiguration() {
securityUtil.logInAs("user1");
//when
ProcessRuntimeConfiguration configuration = processRuntime.configuration();
//then
assertThat(configuration).isNotNull();
//when
List<ProcessRuntimeEventListener<?>> processRuntimeEventListeners = configuration.processEventListeners();
List<VariableEventListener<?>> variableEventListeners = configuration.variableEventListeners();
//then
assertThat(processRuntimeEventListeners).hasSize(10);
assertThat(variableEventListeners).hasSize(3);
}
@Test
public void shouldProcessDefinitions() {
securityUtil.logInAs("user1");
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 50));
List<ProcessDefinition> processDefinitions = processDefinitionPage.getContent();
assertThat(processDefinitions).extracting(ProcessDefinition::getName).contains(
"UserTask Assignee Followed By Group1",
"UserTask Candidate Group",
"UserTask Candidate Group1 Followed by Group2"
);
}
@Test
public void shouldProcessDefinitionsMetaData() {
securityUtil.logInAs("user1");
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 50));
List<ProcessDefinition> processDefinitions = processDefinitionPage.getContent();
assertThat(processDefinitions).extracting(ProcessDefinition::getName).contains(
"UserTask Assignee Followed By Group1",
"UserTask Candidate Group",
"UserTask Candidate Group1 Followed by Group2"
);
}
}
package org.activiti.spring.conformance.set3;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.model.shared.event.VariableCreatedEvent;
import org.activiti.api.model.shared.event.VariableDeletedEvent;
import org.activiti.api.model.shared.event.VariableUpdatedEvent;
import org.activiti.api.process.model.events.BPMNActivityCancelledEvent;
import org.activiti.api.process.model.events.BPMNActivityCompletedEvent;
import org.activiti.api.process.model.events.BPMNActivityStartedEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.runtime.events.*;
import org.activiti.api.process.runtime.events.listener.BPMNElementEventListener;
import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
import org.activiti.api.runtime.shared.events.VariableEventListener;
import org.activiti.api.task.runtime.events.*;
import org.activiti.api.task.runtime.events.listener.TaskEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class Set3RuntimeTestConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(Set3RuntimeTestConfiguration.class);
public static List<RuntimeEvent> collectedEvents = new ArrayList<>();
@Bean
public BPMNElementEventListener<BPMNActivityStartedEvent> bpmnActivityStartedListener() {
return bpmnActivityStartedEvent -> collectedEvents.add(bpmnActivityStartedEvent);
}
@Bean
public BPMNElementEventListener<BPMNActivityCompletedEvent> bpmnActivityCompletedListener() {
return bpmnActivityCompletedEvent -> collectedEvents.add(bpmnActivityCompletedEvent);
}
@Bean
public BPMNElementEventListener<BPMNActivityCancelledEvent> bpmnActivityCancelledListener() {
return bpmnActivityCancelledEvent -> collectedEvents.add(bpmnActivityCancelledEvent);
}
@Bean
public BPMNElementEventListener<BPMNSequenceFlowTakenEvent> bpmnSequenceFlowTakenListener() {
return bpmnSequenceFlowTakenEvent -> collectedEvents.add(bpmnSequenceFlowTakenEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessCreatedEvent> processCreatedListener() {
return processCreatedEvent -> collectedEvents.add(processCreatedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessStartedEvent> processStartedListener() {
return processStartedEvent -> collectedEvents.add(processStartedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessCompletedEvent> processCompletedListener() {
return processCompletedEvent -> collectedEvents.add(processCompletedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessResumedEvent> processResumedListener() {
return processResumedEvent -> collectedEvents.add(processResumedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessSuspendedEvent> processSuspendedListener() {
return processSuspendedEvent -> collectedEvents.add(processSuspendedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessCancelledEvent> processCancelledListener() {
return processCancelledEvent -> collectedEvents.add(processCancelledEvent);
}
@Bean
public VariableEventListener<VariableCreatedEvent> variableCreatedEventListener() {
return variableCreatedEvent -> collectedEvents.add(variableCreatedEvent);
}
@Bean
public VariableEventListener<VariableDeletedEvent> variableDeletedEventListener() {
return variableDeletedEvent -> collectedEvents.add(variableDeletedEvent);
}
@Bean
public VariableEventListener<VariableUpdatedEvent> variableUpdatedEventListener() {
return variableUpdatedEvent -> collectedEvents.add(variableUpdatedEvent);
}
@Bean
public TaskEventListener<TaskCreatedEvent> taskCreatedEventListener() {
return taskCreatedEvent -> collectedEvents.add(taskCreatedEvent);
}
@Bean
public TaskEventListener<TaskUpdatedEvent> taskUpdatedEventListener() {
return taskUpdatedEvent -> collectedEvents.add(taskUpdatedEvent);
}
@Bean
public TaskEventListener<TaskCompletedEvent> taskCompletedEventListener() {
return taskCompletedEvent -> collectedEvents.add(taskCompletedEvent);
}
@Bean
public TaskEventListener<TaskSuspendedEvent> taskSuspendedEventListener() {
return taskSuspendedEvent -> collectedEvents.add(taskSuspendedEvent);
}
@Bean
public TaskEventListener<TaskAssignedEvent> taskAssignedEventListener() {
return taskAssignedEvent -> collectedEvents.add(taskAssignedEvent);
}
}
package org.activiti.spring.conformance.set3;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.activiti.spring.conformance.set3.Set3RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UserTaskCandidateGroupAndAssigneeTest {
private final String processKey = "usertaskas-b5300a4b-8950-4486-ba20-a8d775a3d75d";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldCreateAndCompleteATaskAndDontSeeNext() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
TaskRuntimeEvent.TaskEvents.TASK_COMPLETED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED);
// Check with user1 as he is a candidate
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
List<String> candidateUsers = taskRuntime.userCandidates(task.getId());
assertThat(candidateUsers.size()).isEqualTo(0);
List<String> candidateGroups = taskRuntime.groupCandidates(task.getId());
assertThat(candidateGroups).contains("group1");
// Check with user2 candidates which is not a candidate
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(0);
// Check with user2 candidates which is not a candidate
securityUtil.logInAs("user3");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
}
@After
public void cleanup() {
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for (ProcessInstance pi : processInstancePage.getContent()) {
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
package org.activiti.spring.conformance.set3;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.activiti.spring.conformance.set3.Set3RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UserTaskCandidateGroupsTest {
private final String processKey = "usertaskgr-1a8cdf77-0981-45d4-8080-7cf1a80c973b";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldCreateAndCompleteATaskAndDontSeeNext() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isNull();
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED);
collectedEvents.clear();
taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED,
TaskRuntimeEvent.TaskEvents.TASK_UPDATED);
collectedEvents.clear();
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
TaskRuntimeEvent.TaskEvents.TASK_COMPLETED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED);
// Check with user2 as he is a candidate
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
List<String> candidateUsers = taskRuntime.userCandidates(task.getId());
assertThat(candidateUsers.size()).isEqualTo(0);
List<String> candidateGroups = taskRuntime.groupCandidates(task.getId());
assertThat(candidateGroups).contains("group2");
// Check with user1 candidates which is not a candidate
securityUtil.logInAs("user1");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(0);
// Check with user3 candidates which is a candidate
securityUtil.logInAs("user3");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
}
@After
public void cleanup() {
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for (ProcessInstance pi : processInstancePage.getContent()) {
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
package org.activiti.spring.conformance.set3;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.NotFoundException;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.activiti.spring.conformance.set3.Set3RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UserTaskCandidateVisibilityTest {
private final String processKey = "usertaskca-1e577517-7404-4645-b650-4fbde528f612";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldCreateATaskAndAddNewCandidateUser() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
final Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isNull();
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED);
collectedEvents.clear();
// Check with user2
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(0);
Throwable throwable = catchThrowable(() -> taskRuntime.task(task.getId()));
assertThat(throwable)
.isInstanceOf(NotFoundException.class);
// Check with user1 candidates
securityUtil.logInAs("user1");
taskById = taskRuntime.task(task.getId());
List<String> candidateUsers = taskRuntime.userCandidates(task.getId());
assertThat(candidateUsers).isEmpty();
List<String> candidateGroups = taskRuntime.groupCandidates(task.getId());
assertThat(candidateGroups).contains("group1");
// This should fail because user1 is not the assignee
throwable = catchThrowable(() -> taskRuntime.addCandidateUsers(TaskPayloadBuilder
.addCandidateUsers()
.withTaskId(task.getId())
.withCandidateUser("user2")
.build()));
assertThat(throwable)
.isInstanceOf(IllegalStateException.class);
taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
// Now it should work
taskRuntime.addCandidateUsers(TaskPayloadBuilder
.addCandidateUsers()
.withTaskId(task.getId())
.withCandidateUser("user2")
.build());
candidateUsers = taskRuntime.userCandidates(task.getId());
assertThat(candidateUsers).contains("user2");
// User 1 needs to release the task in order for User 2 see it as candidate
taskRuntime.release(TaskPayloadBuilder.release().withTaskId(task.getId()).build());
// Check with user2
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
}
@Test
public void shouldCreateATaskAndAddNewCandidateGroup() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
final Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isNull();
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED);
collectedEvents.clear();
// Check with user2
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(0);
Throwable throwable = catchThrowable(() -> taskRuntime.task(task.getId()));
assertThat(throwable)
.isInstanceOf(NotFoundException.class);
// Check with user1 candidates
securityUtil.logInAs("user1");
taskById = taskRuntime.task(task.getId());
List<String> candidateUsers = taskRuntime.userCandidates(task.getId());
assertThat(candidateUsers).isEmpty();
List<String> candidateGroups = taskRuntime.groupCandidates(task.getId());
assertThat(candidateGroups).contains("group1");
// This should fail because user1 is not the assignee
throwable = catchThrowable(() -> taskRuntime.addCandidateUsers(TaskPayloadBuilder
.addCandidateUsers()
.withTaskId(task.getId())
.withCandidateUser("user2")
.build()));
assertThat(throwable)
.isInstanceOf(IllegalStateException.class);
taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED,
TaskRuntimeEvent.TaskEvents.TASK_UPDATED);
collectedEvents.clear();
// Now it should work
taskRuntime.addCandidateGroups(TaskPayloadBuilder
.addCandidateGroups()
.withTaskId(task.getId())
.withCandidateGroup("group2")
.build());
//@TODO: operations should cause events
// https://github.com/Activiti/Activiti/issues/2330
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly();
collectedEvents.clear();
candidateGroups = taskRuntime.groupCandidates(task.getId());
assertThat(candidateGroups).contains("group1", "group2");
// User 1 needs to release the task in order for User 2 see it as candidate
taskRuntime.release(TaskPayloadBuilder.release().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED,
TaskRuntimeEvent.TaskEvents.TASK_UPDATED);
collectedEvents.clear();
// Check with user2
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
}
@After
public void cleanup(){
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for(ProcessInstance pi : processInstancePage.getContent()){
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="usertaskas-b5300a4b-8950-4486-ba20-a8d775a3d75d" name="UserTask Assignee Followed By Group1" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>SequenceFlow_1uccvwa</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_1uccvwa" sourceRef="StartEvent_1" targetRef="Task_0pmsax8" />
<bpmn2:sequenceFlow id="SequenceFlow_151v2cg" sourceRef="Task_0pmsax8" targetRef="Task_0rdamee" />
<bpmn2:endEvent id="EndEvent_0zp4rcd">
<bpmn2:incoming>SequenceFlow_0le1m49</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_0le1m49" sourceRef="Task_0rdamee" targetRef="EndEvent_0zp4rcd" />
<bpmn2:userTask id="Task_0pmsax8" name="Task User1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_1uccvwa</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_151v2cg</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_0rdamee" name="Task Group1" activiti:candidateGroups="group1">
<bpmn2:incoming>SequenceFlow_151v2cg</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0le1m49</bpmn2:outgoing>
</bpmn2:userTask>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="usertaskas-b5300a4b-8950-4486-ba20-a8d775a3d75d">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="103" y="33" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="76" y="69" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1uccvwa_di" bpmnElement="SequenceFlow_1uccvwa">
<di:waypoint x="139" y="51" />
<di:waypoint x="189" y="51" />
<bpmndi:BPMNLabel>
<dc:Bounds x="164" y="29.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_151v2cg_di" bpmnElement="SequenceFlow_151v2cg">
<di:waypoint x="289" y="51" />
<di:waypoint x="339" y="51" />
<bpmndi:BPMNLabel>
<dc:Bounds x="314" y="29.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_0zp4rcd_di" bpmnElement="EndEvent_0zp4rcd">
<dc:Bounds x="489" y="33" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="507" y="72" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0le1m49_di" bpmnElement="SequenceFlow_0le1m49">
<di:waypoint x="439" y="51" />
<di:waypoint x="489" y="51" />
<bpmndi:BPMNLabel>
<dc:Bounds x="464" y="29.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_1yqq1gz_di" bpmnElement="Task_0pmsax8">
<dc:Bounds x="189" y="11" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_1dbp00f_di" bpmnElement="Task_0rdamee">
<dc:Bounds x="339" y="11" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="usertaskca-1e577517-7404-4645-b650-4fbde528f612" name="UserTask Candidate Group" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>SequenceFlow_10vblge</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_10vblge" sourceRef="StartEvent_1" targetRef="Task_0r8goei" />
<bpmn2:endEvent id="EndEvent_191qi0q">
<bpmn2:incoming>SequenceFlow_0vf8cap</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_0vf8cap" sourceRef="Task_0r8goei" targetRef="EndEvent_191qi0q" />
<bpmn2:userTask id="Task_0r8goei" name="Task Group 1" activiti:candidateGroups="group1">
<bpmn2:incoming>SequenceFlow_10vblge</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0vf8cap</bpmn2:outgoing>
</bpmn2:userTask>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="usertaskca-1e577517-7404-4645-b650-4fbde528f612">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="157" y="100" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="130" y="136" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_10vblge_di" bpmnElement="SequenceFlow_10vblge">
<di:waypoint x="193" y="118" />
<di:waypoint x="243" y="118" />
<bpmndi:BPMNLabel>
<dc:Bounds x="218" y="96.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_191qi0q_di" bpmnElement="EndEvent_191qi0q">
<dc:Bounds x="393" y="100" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="411" y="139" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0vf8cap_di" bpmnElement="SequenceFlow_0vf8cap">
<di:waypoint x="343" y="118" />
<di:waypoint x="393" y="118" />
<bpmndi:BPMNLabel>
<dc:Bounds x="368" y="96.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_13g60ey_di" bpmnElement="Task_0r8goei">
<dc:Bounds x="243" y="78" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="usertaskgr-1a8cdf77-0981-45d4-8080-7cf1a80c973b" name="UserTask Candidate Group1 Followed by Group2" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>SequenceFlow_052072h</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_052072h" sourceRef="StartEvent_1" targetRef="Task_1dq9dtf" />
<bpmn2:sequenceFlow id="SequenceFlow_0cyfmaw" sourceRef="Task_1dq9dtf" targetRef="Task_0viibyv" />
<bpmn2:endEvent id="EndEvent_1ee100d">
<bpmn2:incoming>SequenceFlow_16g2n05</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_16g2n05" sourceRef="Task_0viibyv" targetRef="EndEvent_1ee100d" />
<bpmn2:userTask id="Task_1dq9dtf" name="Task Group 1" activiti:candidateGroups="group1">
<bpmn2:incoming>SequenceFlow_052072h</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0cyfmaw</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_0viibyv" name="Task Group 2" activiti:candidateGroups="group2">
<bpmn2:incoming>SequenceFlow_0cyfmaw</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_16g2n05</bpmn2:outgoing>
</bpmn2:userTask>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="usertaskgr-1a8cdf77-0981-45d4-8080-7cf1a80c973b">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="121" y="66" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="94" y="102" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_052072h_di" bpmnElement="SequenceFlow_052072h">
<di:waypoint x="157" y="84" />
<di:waypoint x="207" y="84" />
<bpmndi:BPMNLabel>
<dc:Bounds x="182" y="62.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0cyfmaw_di" bpmnElement="SequenceFlow_0cyfmaw">
<di:waypoint x="307" y="84" />
<di:waypoint x="357" y="84" />
<bpmndi:BPMNLabel>
<dc:Bounds x="332" y="62.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_1ee100d_di" bpmnElement="EndEvent_1ee100d">
<dc:Bounds x="507" y="66" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="525" y="105" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_16g2n05_di" bpmnElement="SequenceFlow_16g2n05">
<di:waypoint x="457" y="84" />
<di:waypoint x="507" y="84" />
<bpmndi:BPMNLabel>
<dc:Bounds x="482" y="62.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_10d3usd_di" bpmnElement="Task_1dq9dtf">
<dc:Bounds x="207" y="44" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_1rlpea8_di" bpmnElement="Task_0viibyv">
<dc:Bounds x="357" y="44" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-conformance-tests</artifactId>
<version>7.0.0-SNAPSHOT</version>
</parent>
<artifactId>activiti-spring-conformance-set4</artifactId>
<packaging>jar</packaging>
<name>Activiti Spring :: Conformance Set 4</name>
<description>Activiti Spring :: Conformance Set 4</description>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-conformance-util</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-process-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-task-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-runtime-shared</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-task-model</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-process-model</artifactId>
</dependency>
<dependency>
<groupId>org.activiti.api</groupId>
<artifactId>activiti-api-model-shared</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package org.activiti.spring.conformance.set4;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
package org.activiti.spring.conformance.set4;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.NotFoundException;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.ActivitiException;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.activiti.spring.conformance.set4.Set4RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class BasicExclusiveGatewayErrorTest {
private final String processKey = "basicexclu-15cdd4ac-ff4d-4925-9b4e-err";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldFailOnExpressionError() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
Throwable throwable = catchThrowable(() -> taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build()));
//@TODO: this is leaking ActivitiException.class we should validate expressions before running the process
// https://github.com/Activiti/Activiti/issues/2328
assertThat(throwable)
.isInstanceOf(ActivitiException.class);
assertThat(throwable).
hasMessageContaining("condition expression returns non-Boolean");
}
@After
public void cleanup() {
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for (ProcessInstance pi : processInstancePage.getContent()) {
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
package org.activiti.spring.conformance.set4;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.activiti.spring.conformance.set4.Set4RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class BasicExclusiveGatewayTest {
private final String processKey = "basicexclu-15cdd4ac-ff4d-4925-9b4e-87ea77528613";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldCreateAndCompleteATaskAndDontSeeNext() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
TaskRuntimeEvent.TaskEvents.TASK_COMPLETED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
}
@After
public void cleanup() {
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for (ProcessInstance pi : processInstancePage.getContent()) {
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
package org.activiti.spring.conformance.set4;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.activiti.spring.conformance.set4.Set4RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class BasicParallelGatewayGroupAssignmentsTest {
private final String processKey = "basicparal-41c130f7-0b06-4bbb-aee4-73667298e369";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldCheckThatParallelGatewayCreateBothTasksForGroups() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.contains(
TaskRuntimeEvent.TaskEvents.TASK_COMPLETED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED);
collectedEvents.clear();
// User 1 is a candidate for a task
securityUtil.logInAs("user1");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isNull();
// User 2 is a candidate for a task
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.CREATED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isNull();
// User 3 is a candidate for both tasks
securityUtil.logInAs("user3");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(2);
}
@After
public void cleanup() {
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for (ProcessInstance pi : processInstancePage.getContent()) {
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
package org.activiti.spring.conformance.set4;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.events.BPMNActivityEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
import org.activiti.api.process.runtime.ProcessAdminRuntime;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.events.TaskRuntimeEvent;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.activiti.spring.conformance.set4.Set4RuntimeTestConfiguration.collectedEvents;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class BasicParallelGatewayTest {
private final String processKey = "basicparal-b1db86dd-4a15-4c0e-9168-25d9c42d53ee";
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private ProcessAdminRuntime processAdminRuntime;
@Before
public void cleanUp() {
collectedEvents.clear();
}
@Test
public void shouldCheckThatParallelGatewayCreateTwoAssignedTasks() {
securityUtil.logInAs("user1");
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey(processKey)
.withBusinessKey("my-business-key")
.withProcessInstanceName("my-process-instance-name")
.build());
//then
assertThat(processInstance).isNotNull();
assertThat(processInstance.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
assertThat(processInstance.getBusinessKey()).isEqualTo("my-business-key");
assertThat(processInstance.getName()).isEqualTo("my-process-instance-name");
// I should be able to get the process instance from the Runtime because it is still running
ProcessInstance processInstanceById = processRuntime.processInstance(processInstance.getId());
assertThat(processInstanceById).isEqualTo(processInstance);
// I should get a task for User1
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
Task task = tasks.getContent().get(0);
Task taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.containsExactly(
ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED,
ProcessRuntimeEvent.ProcessEvents.PROCESS_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
assertThat(collectedEvents)
.extracting(RuntimeEvent::getEventType)
.contains(
TaskRuntimeEvent.TaskEvents.TASK_COMPLETED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
BPMNActivityEvent.ActivityEvents.ACTIVITY_COMPLETED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED,
BPMNSequenceFlowTakenEvent.SequenceFlowEvents.SEQUENCE_FLOW_TAKEN,
BPMNActivityEvent.ActivityEvents.ACTIVITY_STARTED,
TaskRuntimeEvent.TaskEvents.TASK_CREATED,
TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED);
collectedEvents.clear();
// User 1 has his/her task
securityUtil.logInAs("user1");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user1");
// User 2 has his/her task
securityUtil.logInAs("user2");
tasks = taskRuntime.tasks(Pageable.of(0, 50));
assertThat(tasks.getTotalItems()).isEqualTo(1);
task = tasks.getContent().get(0);
taskById = taskRuntime.task(task.getId());
assertThat(taskById.getStatus()).isEqualTo(Task.TaskStatus.ASSIGNED);
assertThat(task).isEqualTo(taskById);
assertThat(task.getAssignee()).isEqualTo("user2");
}
@After
public void cleanup() {
securityUtil.logInAs("admin");
Page<ProcessInstance> processInstancePage = processAdminRuntime.processInstances(Pageable.of(0, 50));
for (ProcessInstance pi : processInstancePage.getContent()) {
processAdminRuntime.delete(ProcessPayloadBuilder.delete(pi.getId()));
}
}
}
package org.activiti.spring.conformance.set4;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessDefinitionMeta;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.process.runtime.conf.ProcessRuntimeConfiguration;
import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
import org.activiti.api.runtime.shared.events.VariableEventListener;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.activiti.spring.conformance.util.security.SecurityUtil;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class ConformanceBasicProcessRuntimeTest {
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private SecurityUtil securityUtil;
@Test
public void shouldGetConfiguration() {
securityUtil.logInAs("user1");
//when
ProcessRuntimeConfiguration configuration = processRuntime.configuration();
//then
assertThat(configuration).isNotNull();
//when
List<ProcessRuntimeEventListener<?>> processRuntimeEventListeners = configuration.processEventListeners();
List<VariableEventListener<?>> variableEventListeners = configuration.variableEventListeners();
//then
assertThat(processRuntimeEventListeners).hasSize(10);
assertThat(variableEventListeners).hasSize(3);
}
@Test
public void shouldProcessDefinitions() {
securityUtil.logInAs("user1");
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 50));
List<ProcessDefinition> processDefinitions = processDefinitionPage.getContent();
assertThat(processDefinitions).extracting(ProcessDefinition::getName).contains(
"Basic Exclusive Gateway",
"Basic Exclusive Gateway Expr Error",
"Basic Parallel Gateway",
"Basic Parallel Gateway Groups"
);
}
@Test
public void shouldProcessDefinitionsMetaData() {
securityUtil.logInAs("user1");
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 50));
List<ProcessDefinition> processDefinitions = processDefinitionPage.getContent();
assertThat(processDefinitions).extracting(ProcessDefinition::getName).contains(
"Basic Exclusive Gateway",
"Basic Exclusive Gateway Expr Error",
"Basic Parallel Gateway",
"Basic Parallel Gateway Groups"
);
}
}
package org.activiti.spring.conformance.set4;
import org.activiti.api.model.shared.event.RuntimeEvent;
import org.activiti.api.model.shared.event.VariableCreatedEvent;
import org.activiti.api.model.shared.event.VariableDeletedEvent;
import org.activiti.api.model.shared.event.VariableUpdatedEvent;
import org.activiti.api.process.model.events.BPMNActivityCancelledEvent;
import org.activiti.api.process.model.events.BPMNActivityCompletedEvent;
import org.activiti.api.process.model.events.BPMNActivityStartedEvent;
import org.activiti.api.process.model.events.BPMNSequenceFlowTakenEvent;
import org.activiti.api.process.runtime.events.*;
import org.activiti.api.process.runtime.events.listener.BPMNElementEventListener;
import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
import org.activiti.api.runtime.shared.events.VariableEventListener;
import org.activiti.api.task.runtime.events.*;
import org.activiti.api.task.runtime.events.listener.TaskEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class Set4RuntimeTestConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(Set4RuntimeTestConfiguration.class);
public static List<RuntimeEvent> collectedEvents = new ArrayList<>();
@Bean
public BPMNElementEventListener<BPMNActivityStartedEvent> bpmnActivityStartedListener() {
return bpmnActivityStartedEvent -> collectedEvents.add(bpmnActivityStartedEvent);
}
@Bean
public BPMNElementEventListener<BPMNActivityCompletedEvent> bpmnActivityCompletedListener() {
return bpmnActivityCompletedEvent -> collectedEvents.add(bpmnActivityCompletedEvent);
}
@Bean
public BPMNElementEventListener<BPMNActivityCancelledEvent> bpmnActivityCancelledListener() {
return bpmnActivityCancelledEvent -> collectedEvents.add(bpmnActivityCancelledEvent);
}
@Bean
public BPMNElementEventListener<BPMNSequenceFlowTakenEvent> bpmnSequenceFlowTakenListener() {
return bpmnSequenceFlowTakenEvent -> collectedEvents.add(bpmnSequenceFlowTakenEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessCreatedEvent> processCreatedListener() {
return processCreatedEvent -> collectedEvents.add(processCreatedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessStartedEvent> processStartedListener() {
return processStartedEvent -> collectedEvents.add(processStartedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessCompletedEvent> processCompletedListener() {
return processCompletedEvent -> collectedEvents.add(processCompletedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessResumedEvent> processResumedListener() {
return processResumedEvent -> collectedEvents.add(processResumedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessSuspendedEvent> processSuspendedListener() {
return processSuspendedEvent -> collectedEvents.add(processSuspendedEvent);
}
@Bean
public ProcessRuntimeEventListener<ProcessCancelledEvent> processCancelledListener() {
return processCancelledEvent -> collectedEvents.add(processCancelledEvent);
}
@Bean
public VariableEventListener<VariableCreatedEvent> variableCreatedEventListener() {
return variableCreatedEvent -> collectedEvents.add(variableCreatedEvent);
}
@Bean
public VariableEventListener<VariableDeletedEvent> variableDeletedEventListener() {
return variableDeletedEvent -> collectedEvents.add(variableDeletedEvent);
}
@Bean
public VariableEventListener<VariableUpdatedEvent> variableUpdatedEventListener() {
return variableUpdatedEvent -> collectedEvents.add(variableUpdatedEvent);
}
@Bean
public TaskEventListener<TaskCreatedEvent> taskCreatedEventListener() {
return taskCreatedEvent -> collectedEvents.add(taskCreatedEvent);
}
@Bean
public TaskEventListener<TaskUpdatedEvent> taskUpdatedEventListener() {
return taskUpdatedEvent -> collectedEvents.add(taskUpdatedEvent);
}
@Bean
public TaskEventListener<TaskCompletedEvent> taskCompletedEventListener() {
return taskCompletedEvent -> collectedEvents.add(taskCompletedEvent);
}
@Bean
public TaskEventListener<TaskSuspendedEvent> taskSuspendedEventListener() {
return taskSuspendedEvent -> collectedEvents.add(taskSuspendedEvent);
}
@Bean
public TaskEventListener<TaskAssignedEvent> taskAssignedEventListener() {
return taskAssignedEvent -> collectedEvents.add(taskAssignedEvent);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="basicexclu-15cdd4ac-ff4d-4925-9b4e-err" name="Basic Exclusive Gateway Expr Error" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>SequenceFlow_1035s34</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_1035s34" sourceRef="StartEvent_1" targetRef="Task_1fhojlw" />
<bpmn2:exclusiveGateway id="ExclusiveGateway_1ri35t5">
<bpmn2:incoming>SequenceFlow_0pdm5j0</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1tut9mk</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_1betql9</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="SequenceFlow_0pdm5j0" sourceRef="Task_1fhojlw" targetRef="ExclusiveGateway_1ri35t5" />
<bpmn2:sequenceFlow id="SequenceFlow_1tut9mk" sourceRef="ExclusiveGateway_1ri35t5" targetRef="Task_0pbjier">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">err</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_1betql9" sourceRef="ExclusiveGateway_1ri35t5" targetRef="Task_16mkqfn">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">err</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:endEvent id="EndEvent_0l4lyvt">
<bpmn2:incoming>SequenceFlow_15iqzbb</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_15iqzbb" sourceRef="Task_16mkqfn" targetRef="EndEvent_0l4lyvt" />
<bpmn2:endEvent id="EndEvent_16qpwr2">
<bpmn2:incoming>SequenceFlow_1na0oew</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_1na0oew" sourceRef="Task_0pbjier" targetRef="EndEvent_16qpwr2" />
<bpmn2:userTask id="Task_1fhojlw" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_1035s34</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0pdm5j0</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_0pbjier" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_1tut9mk</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1na0oew</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_16mkqfn" name="User Task User 2" activiti:assignee="user2">
<bpmn2:incoming>SequenceFlow_1betql9</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_15iqzbb</bpmn2:outgoing>
</bpmn2:userTask>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="basicexclu-15cdd4ac-ff4d-4925-9b4e-87ea77528613">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="90" y="57" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="63" y="93" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1035s34_di" bpmnElement="SequenceFlow_1035s34">
<di:waypoint x="126" y="75" />
<di:waypoint x="176" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="151" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ExclusiveGateway_1ri35t5_di" bpmnElement="ExclusiveGateway_1ri35t5" isMarkerVisible="true">
<dc:Bounds x="326" y="50" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="351" y="26.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0pdm5j0_di" bpmnElement="SequenceFlow_0pdm5j0">
<di:waypoint x="226" y="75" />
<di:waypoint x="326" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="276" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1tut9mk_di" bpmnElement="SequenceFlow_1tut9mk">
<di:waypoint x="376" y="75" />
<di:waypoint x="476" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="426" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1betql9_di" bpmnElement="SequenceFlow_1betql9">
<di:waypoint x="351" y="100" />
<di:waypoint x="351" y="185" />
<di:waypoint x="476" y="185" />
<bpmndi:BPMNLabel>
<dc:Bounds x="366" y="136" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_0l4lyvt_di" bpmnElement="EndEvent_0l4lyvt">
<dc:Bounds x="576" y="167" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="594" y="206" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_15iqzbb_di" bpmnElement="SequenceFlow_15iqzbb">
<di:waypoint x="526" y="185" />
<di:waypoint x="576" y="185" />
<bpmndi:BPMNLabel>
<dc:Bounds x="551" y="163.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_16qpwr2_di" bpmnElement="EndEvent_16qpwr2">
<dc:Bounds x="576" y="57" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="594" y="96" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1na0oew_di" bpmnElement="SequenceFlow_1na0oew">
<di:waypoint x="526" y="75" />
<di:waypoint x="576" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="551" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_14cvhj1_di" bpmnElement="Task_1fhojlw">
<dc:Bounds x="176" y="35" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_0ha77lo_di" bpmnElement="Task_0pbjier">
<dc:Bounds x="426" y="35" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_13gtmpu_di" bpmnElement="Task_16mkqfn">
<dc:Bounds x="426" y="145" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="basicexclu-15cdd4ac-ff4d-4925-9b4e-87ea77528613" name="Basic Exclusive Gateway" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>SequenceFlow_1035s34</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_1035s34" sourceRef="StartEvent_1" targetRef="Task_1fhojlw" />
<bpmn2:exclusiveGateway id="ExclusiveGateway_1ri35t5">
<bpmn2:incoming>SequenceFlow_0pdm5j0</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1tut9mk</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_1betql9</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="SequenceFlow_0pdm5j0" sourceRef="Task_1fhojlw" targetRef="ExclusiveGateway_1ri35t5" />
<bpmn2:sequenceFlow id="SequenceFlow_1tut9mk" sourceRef="ExclusiveGateway_1ri35t5" targetRef="Task_0pbjier">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${true}</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_1betql9" sourceRef="ExclusiveGateway_1ri35t5" targetRef="Task_16mkqfn">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${false}</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:endEvent id="EndEvent_0l4lyvt">
<bpmn2:incoming>SequenceFlow_15iqzbb</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_15iqzbb" sourceRef="Task_16mkqfn" targetRef="EndEvent_0l4lyvt" />
<bpmn2:endEvent id="EndEvent_16qpwr2">
<bpmn2:incoming>SequenceFlow_1na0oew</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_1na0oew" sourceRef="Task_0pbjier" targetRef="EndEvent_16qpwr2" />
<bpmn2:userTask id="Task_1fhojlw" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_1035s34</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0pdm5j0</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_0pbjier" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_1tut9mk</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1na0oew</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_16mkqfn" name="User Task User 2" activiti:assignee="user2">
<bpmn2:incoming>SequenceFlow_1betql9</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_15iqzbb</bpmn2:outgoing>
</bpmn2:userTask>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="basicexclu-15cdd4ac-ff4d-4925-9b4e-87ea77528613">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="90" y="57" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="63" y="93" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1035s34_di" bpmnElement="SequenceFlow_1035s34">
<di:waypoint x="126" y="75" />
<di:waypoint x="176" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="151" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ExclusiveGateway_1ri35t5_di" bpmnElement="ExclusiveGateway_1ri35t5" isMarkerVisible="true">
<dc:Bounds x="326" y="50" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="351" y="26.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0pdm5j0_di" bpmnElement="SequenceFlow_0pdm5j0">
<di:waypoint x="226" y="75" />
<di:waypoint x="326" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="276" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1tut9mk_di" bpmnElement="SequenceFlow_1tut9mk">
<di:waypoint x="376" y="75" />
<di:waypoint x="476" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="426" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1betql9_di" bpmnElement="SequenceFlow_1betql9">
<di:waypoint x="351" y="100" />
<di:waypoint x="351" y="185" />
<di:waypoint x="476" y="185" />
<bpmndi:BPMNLabel>
<dc:Bounds x="366" y="136" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_0l4lyvt_di" bpmnElement="EndEvent_0l4lyvt">
<dc:Bounds x="576" y="167" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="594" y="206" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_15iqzbb_di" bpmnElement="SequenceFlow_15iqzbb">
<di:waypoint x="526" y="185" />
<di:waypoint x="576" y="185" />
<bpmndi:BPMNLabel>
<dc:Bounds x="551" y="163.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_16qpwr2_di" bpmnElement="EndEvent_16qpwr2">
<dc:Bounds x="576" y="57" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="594" y="96" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1na0oew_di" bpmnElement="SequenceFlow_1na0oew">
<di:waypoint x="526" y="75" />
<di:waypoint x="576" y="75" />
<bpmndi:BPMNLabel>
<dc:Bounds x="551" y="53.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_14cvhj1_di" bpmnElement="Task_1fhojlw">
<dc:Bounds x="176" y="35" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_0ha77lo_di" bpmnElement="Task_0pbjier">
<dc:Bounds x="426" y="35" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_13gtmpu_di" bpmnElement="Task_16mkqfn">
<dc:Bounds x="426" y="145" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="basicparal-41c130f7-0b06-4bbb-aee4-73667298e369" name="Basic Parallel Gateway Groups" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1njo0fq">
<bpmn2:outgoing>SequenceFlow_1deq42g</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:parallelGateway id="ParallelGateway_1sa9tx3">
<bpmn2:incoming>SequenceFlow_0uqnr3f</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1bnuihc</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_1w72n38</bpmn2:outgoing>
</bpmn2:parallelGateway>
<bpmn2:endEvent id="EndEvent_0v1rx2p">
<bpmn2:incoming>SequenceFlow_1lqk19w</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:endEvent id="EndEvent_1rjew8q">
<bpmn2:incoming>SequenceFlow_0yybgo4</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:userTask id="UserTask_023rlgq" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_1deq42g</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0uqnr3f</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="UserTask_11rotpk" name="User Task Group 1" activiti:assignee="" activiti:candidateGroups="group1">
<bpmn2:incoming>SequenceFlow_1bnuihc</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0yybgo4</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="UserTask_1ycbkqb" name="User Task Group 2" activiti:assignee="" activiti:candidateGroups="group2">
<bpmn2:incoming>SequenceFlow_1w72n38</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1lqk19w</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="SequenceFlow_1deq42g" sourceRef="StartEvent_1njo0fq" targetRef="UserTask_023rlgq" />
<bpmn2:sequenceFlow id="SequenceFlow_0uqnr3f" sourceRef="UserTask_023rlgq" targetRef="ParallelGateway_1sa9tx3" />
<bpmn2:sequenceFlow id="SequenceFlow_1bnuihc" sourceRef="ParallelGateway_1sa9tx3" targetRef="UserTask_11rotpk" />
<bpmn2:sequenceFlow id="SequenceFlow_1w72n38" sourceRef="ParallelGateway_1sa9tx3" targetRef="UserTask_1ycbkqb" />
<bpmn2:sequenceFlow id="SequenceFlow_1lqk19w" sourceRef="UserTask_1ycbkqb" targetRef="EndEvent_0v1rx2p" />
<bpmn2:sequenceFlow id="SequenceFlow_0yybgo4" sourceRef="UserTask_11rotpk" targetRef="EndEvent_1rjew8q" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="basicparal-41c130f7-0b06-4bbb-aee4-73667298e369">
<bpmndi:BPMNShape id="StartEvent_1njo0fq_di" bpmnElement="StartEvent_1njo0fq">
<dc:Bounds x="110" y="192" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="83" y="228" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ParallelGateway_1sa9tx3_di" bpmnElement="ParallelGateway_1sa9tx3">
<dc:Bounds x="346" y="185" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="371" y="161.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="EndEvent_0v1rx2p_di" bpmnElement="EndEvent_0v1rx2p">
<dc:Bounds x="596" y="302" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="614" y="341" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="EndEvent_1rjew8q_di" bpmnElement="EndEvent_1rjew8q">
<dc:Bounds x="596" y="192" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="614" y="231" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_023rlgq_di" bpmnElement="UserTask_023rlgq">
<dc:Bounds x="196" y="170" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_11rotpk_di" bpmnElement="UserTask_11rotpk">
<dc:Bounds x="446" y="170" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_1ycbkqb_di" bpmnElement="UserTask_1ycbkqb">
<dc:Bounds x="446" y="280" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1deq42g_di" bpmnElement="SequenceFlow_1deq42g">
<di:waypoint x="146" y="210" />
<di:waypoint x="196" y="210" />
<bpmndi:BPMNLabel>
<dc:Bounds x="171" y="189" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0uqnr3f_di" bpmnElement="SequenceFlow_0uqnr3f">
<di:waypoint x="246" y="210" />
<di:waypoint x="346" y="210" />
<bpmndi:BPMNLabel>
<dc:Bounds x="296" y="189" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1bnuihc_di" bpmnElement="SequenceFlow_1bnuihc">
<di:waypoint x="396" y="210" />
<di:waypoint x="496" y="210" />
<bpmndi:BPMNLabel>
<dc:Bounds x="446" y="189" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1w72n38_di" bpmnElement="SequenceFlow_1w72n38">
<di:waypoint x="371" y="235" />
<di:waypoint x="371" y="320" />
<di:waypoint x="496" y="320" />
<bpmndi:BPMNLabel>
<dc:Bounds x="386" y="271.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1lqk19w_di" bpmnElement="SequenceFlow_1lqk19w">
<di:waypoint x="546" y="320" />
<di:waypoint x="596" y="320" />
<bpmndi:BPMNLabel>
<dc:Bounds x="571" y="299" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0yybgo4_di" bpmnElement="SequenceFlow_0yybgo4">
<di:waypoint x="546" y="210" />
<di:waypoint x="596" y="210" />
<bpmndi:BPMNLabel>
<dc:Bounds x="571" y="189" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="basicparal-b1db86dd-4a15-4c0e-9168-25d9c42d53ee" name="Basic Parallel Gateway" isExecutable="true">
<bpmn2:documentation />
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>SequenceFlow_0zyqlmv</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_0zyqlmv" sourceRef="StartEvent_1" targetRef="Task_1p6c1pp" />
<bpmn2:sequenceFlow id="SequenceFlow_193b2u1" sourceRef="Task_1p6c1pp" targetRef="ExclusiveGateway_11w4myo" />
<bpmn2:parallelGateway id="ExclusiveGateway_11w4myo">
<bpmn2:incoming>SequenceFlow_193b2u1</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_0l4z512</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_1xq89lk</bpmn2:outgoing>
</bpmn2:parallelGateway>
<bpmn2:sequenceFlow id="SequenceFlow_0l4z512" sourceRef="ExclusiveGateway_11w4myo" targetRef="Task_099d84c" />
<bpmn2:sequenceFlow id="SequenceFlow_1xq89lk" sourceRef="ExclusiveGateway_11w4myo" targetRef="Task_0ufr8ss" />
<bpmn2:endEvent id="EndEvent_149gax9">
<bpmn2:incoming>SequenceFlow_19475d9</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_19475d9" sourceRef="Task_0ufr8ss" targetRef="EndEvent_149gax9" />
<bpmn2:endEvent id="EndEvent_16pls2w">
<bpmn2:incoming>SequenceFlow_08i9pa2</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="SequenceFlow_08i9pa2" sourceRef="Task_099d84c" targetRef="EndEvent_16pls2w" />
<bpmn2:userTask id="Task_1p6c1pp" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_0zyqlmv</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_193b2u1</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_099d84c" name="User Task User 1" activiti:assignee="user1">
<bpmn2:incoming>SequenceFlow_0l4z512</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_08i9pa2</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="Task_0ufr8ss" name="User Task User 2" activiti:assignee="user2">
<bpmn2:incoming>SequenceFlow_1xq89lk</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_19475d9</bpmn2:outgoing>
</bpmn2:userTask>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="basicparal-b1db86dd-4a15-4c0e-9168-25d9c42d53ee">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="124" y="14" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="97" y="50" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0zyqlmv_di" bpmnElement="SequenceFlow_0zyqlmv">
<di:waypoint x="160" y="32" />
<di:waypoint x="210" y="32" />
<bpmndi:BPMNLabel>
<dc:Bounds x="185" y="10.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_193b2u1_di" bpmnElement="SequenceFlow_193b2u1">
<di:waypoint x="260" y="32" />
<di:waypoint x="360" y="32" />
<bpmndi:BPMNLabel>
<dc:Bounds x="310" y="10.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ParallelGateway_13dx4dw_di" bpmnElement="ExclusiveGateway_11w4myo">
<dc:Bounds x="360" y="7" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="385" y="-16.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0l4z512_di" bpmnElement="SequenceFlow_0l4z512">
<di:waypoint x="410" y="32" />
<di:waypoint x="510" y="32" />
<bpmndi:BPMNLabel>
<dc:Bounds x="460" y="10.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1xq89lk_di" bpmnElement="SequenceFlow_1xq89lk">
<di:waypoint x="385" y="57" />
<di:waypoint x="385" y="142" />
<di:waypoint x="510" y="142" />
<bpmndi:BPMNLabel>
<dc:Bounds x="400" y="93" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_149gax9_di" bpmnElement="EndEvent_149gax9">
<dc:Bounds x="610" y="124" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="628" y="163" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_19475d9_di" bpmnElement="SequenceFlow_19475d9">
<di:waypoint x="560" y="142" />
<di:waypoint x="610" y="142" />
<bpmndi:BPMNLabel>
<dc:Bounds x="585" y="120.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_16pls2w_di" bpmnElement="EndEvent_16pls2w">
<dc:Bounds x="610" y="14" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="628" y="53" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_08i9pa2_di" bpmnElement="SequenceFlow_08i9pa2">
<di:waypoint x="560" y="32" />
<di:waypoint x="610" y="32" />
<bpmndi:BPMNLabel>
<dc:Bounds x="585" y="10.5" width="0" height="13" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_0fs8vz8_di" bpmnElement="Task_1p6c1pp">
<dc:Bounds x="210" y="-8" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_0dhd8c2_di" bpmnElement="Task_099d84c">
<dc:Bounds x="460" y="-8" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="UserTask_1wqld7v_di" bpmnElement="Task_0ufr8ss">
<dc:Bounds x="460" y="102" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
......@@ -20,5 +20,7 @@
<module>activiti-spring-conformance-set0</module>
<module>activiti-spring-conformance-set1</module>
<module>activiti-spring-conformance-set2</module>
<module>activiti-spring-conformance-set3</module>
<module>activiti-spring-conformance-set4</module>
</modules>
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册