Update javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java

update to use the givenX_whenY_thenZ naming convention for tests

Co-Authored-By: KevinGilmore <kpg102@gmail.com>
This commit is contained in:
Yavuz Tas
2019-10-29 10:02:27 +01:00
committed by GitHub
parent db85c8f275
commit e28fd3e7c9
20479 changed files with 1642089 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
## Spring Activiti
This module contains articles about Spring with Activiti
### Relevant articles
- [A Guide to Activiti with Java](https://www.baeldung.com/java-activiti)
- [Introduction to Activiti with Spring](https://www.baeldung.com/spring-activiti)
- [Activiti with Spring Security](https://www.baeldung.com/activiti-spring-security)
- [ProcessEngine Configuration in Activiti](https://www.baeldung.com/activiti-process-engine)
+64
View File
@@ -0,0 +1,64 @@
<?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>
<artifactId>spring-activiti</artifactId>
<name>spring-activiti</name>
<packaging>jar</packaging>
<description>Demo project for Spring Boot</description>
<parent>
<artifactId>parent-boot-1</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-1</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-security</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.baeldung.activitiwithspring.ActivitiWithSpringApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<activiti.version>6.0.0</activiti.version>
</properties>
</project>
@@ -0,0 +1,20 @@
package com.baeldung.activiti.security.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login")
.setViewName("login");
registry.addViewController("/homepage")
.setViewName("homepage");
}
}
@@ -0,0 +1,54 @@
package com.baeldung.activiti.security.config;
import java.util.List;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProcessController {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private IdentityService identityService;
@Autowired
SpringProcessEngineConfiguration config;
@GetMapping("/protected-process")
public String startProcess() {
String userId = SecurityContextHolder.getContext()
.getAuthentication()
.getName();
identityService.setAuthenticatedUserId(userId);
ProcessInstance pi = runtimeService.startProcessInstanceByKey("protected-process");
List<Task> usertasks = taskService.createTaskQuery()
.processInstanceId(pi.getId())
.list();
taskService.complete(usertasks.iterator()
.next()
.getId());
return "Process started. Number of currently running process instances = " + runtimeService.createProcessInstanceQuery()
.count();
}
}
@@ -0,0 +1,86 @@
package com.baeldung.activiti.security.config;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.GroupQuery;
import org.activiti.engine.impl.GroupQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.persistence.entity.GroupEntityImpl;
import org.activiti.engine.impl.persistence.entity.GroupEntityManagerImpl;
import org.activiti.engine.impl.persistence.entity.data.GroupDataManager;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
public class SpringSecurityGroupManager extends GroupEntityManagerImpl {
private JdbcUserDetailsManager userManager;
public SpringSecurityGroupManager(ProcessEngineConfigurationImpl processEngineConfiguration, GroupDataManager groupDataManager) {
super(processEngineConfiguration, groupDataManager);
}
@Override
public List<Group> findGroupByQueryCriteria(GroupQueryImpl query, Page page) {
if (query.getUserId() != null) {
return findGroupsByUser(query.getUserId());
}
return null;
}
@Override
public long findGroupCountByQueryCriteria(GroupQueryImpl query) {
return findGroupByQueryCriteria(query, null).size();
}
@Override
public List<Group> findGroupsByUser(String userId) {
UserDetails userDetails = userManager.loadUserByUsername(userId);
System.out.println("group manager");
if (userDetails != null) {
List<Group> groups = userDetails.getAuthorities()
.stream()
.map(a -> a.getAuthority())
.map(a -> {
Group g = new GroupEntityImpl();
g.setId(a);
return g;
})
.collect(Collectors.toList());
return groups;
}
return null;
}
public void setUserManager(JdbcUserDetailsManager userManager) {
this.userManager = userManager;
}
public Group createNewGroup(String groupId) {
throw new UnsupportedOperationException("This operation is not supported!");
}
@Override
public void delete(String groupId) {
throw new UnsupportedOperationException("This operation is not supported!");
}
public GroupQuery createNewGroupQuery() {
throw new UnsupportedOperationException("This operation is not supported!");
}
public List<Group> findGroupsByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) {
throw new UnsupportedOperationException("This operation is not supported!");
}
public long findGroupCountByNativeQuery(Map<String, Object> parameterMap) {
throw new UnsupportedOperationException("This operation is not supported!");
}
}
@@ -0,0 +1,144 @@
package com.baeldung.activiti.security.config;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.identity.UserQuery;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.UserQueryImpl;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.persistence.entity.GroupEntityImpl;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.activiti.engine.impl.persistence.entity.UserEntityImpl;
import org.activiti.engine.impl.persistence.entity.UserEntityManagerImpl;
import org.activiti.engine.impl.persistence.entity.data.UserDataManager;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
public class SpringSecurityUserManager extends UserEntityManagerImpl {
private JdbcUserDetailsManager userManager;
public SpringSecurityUserManager(ProcessEngineConfigurationImpl processEngineConfiguration, UserDataManager userDataManager, JdbcUserDetailsManager userManager) {
super(processEngineConfiguration, userDataManager);
this.userManager = userManager;
}
@Override
public UserEntity findById(String userId) {
UserDetails userDetails = userManager.loadUserByUsername(userId);
if (userDetails != null) {
UserEntityImpl user = new UserEntityImpl();
user.setId(userId);
return user;
}
return null;
}
@Override
public List<User> findUserByQueryCriteria(UserQueryImpl query, Page page) {
List<User> users = null;
if (query.getGroupId() != null) {
users = userManager.findUsersInGroup(query.getGroupId())
.stream()
.map(username -> {
User user = new UserEntityImpl();
user.setId(username);
return user;
})
.collect(Collectors.toList());
if (page != null) {
return users.subList(page.getFirstResult(), page.getFirstResult() + page.getMaxResults());
}
return users;
}
if (query.getId() != null) {
UserDetails userDetails = userManager.loadUserByUsername(query.getId());
if (userDetails != null) {
UserEntityImpl user = new UserEntityImpl();
user.setId(query.getId());
return Collections.singletonList(user);
}
}
return null;
}
@Override
public Boolean checkPassword(String userId, String password) {
return true;
}
public void setUserManager(JdbcUserDetailsManager userManager) {
this.userManager = userManager;
}
public User createNewUser(String userId) {
throw new UnsupportedOperationException("This operation is not supported!");
}
public void updateUser(User updatedUser) {
throw new UnsupportedOperationException("This operation is not supported!");
}
public void delete(UserEntity userEntity) {
throw new UnsupportedOperationException("This operation is not supported!");
}
@Override
public void deletePicture(User user) {
UserEntity userEntity = (UserEntity) user;
if (userEntity.getPictureByteArrayRef() != null) {
userEntity.getPictureByteArrayRef()
.delete();
}
}
public void delete(String userId) {
throw new UnsupportedOperationException("This operation is not supported!");
}
public long findUserCountByQueryCriteria(UserQueryImpl query) {
return findUserByQueryCriteria(query, null).size();
}
public List<Group> findGroupsByUser(String userId) {
UserDetails userDetails = userManager.loadUserByUsername(userId);
if (userDetails != null) {
List<Group> groups = userDetails.getAuthorities()
.stream()
.map(a -> a.getAuthority())
.map(a -> {
Group g = new GroupEntityImpl();
g.setId(a);
return g;
})
.collect(Collectors.toList());
return groups;
}
return null;
}
public UserQuery createNewUserQuery() {
throw new UnsupportedOperationException("This operation is not supported!");
}
public List<User> findUsersByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) {
throw new UnsupportedOperationException("This operation is not supported!");
}
public long findUserCountByNativeQuery(Map<String, Object> parameterMap) {
throw new UnsupportedOperationException("This operation is not supported!");
}
}
@@ -0,0 +1,47 @@
package com.baeldung.activiti.security.withactiviti;
import org.activiti.engine.IdentityService;
import org.activiti.spring.security.IdentityServiceUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/protected-process*")
.authenticated()
.anyRequest()
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/homepage")
.failureUrl("/login?error=true")
.and()
.csrf()
.disable()
.logout()
.logoutSuccessUrl("/login");
}
@Autowired
private IdentityService identityService;
@Bean
public IdentityServiceUserDetailsService userDetailsService() {
return new IdentityServiceUserDetailsService(identityService);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}
}
@@ -0,0 +1,34 @@
package com.baeldung.activiti.security.withactiviti;
import org.activiti.engine.IdentityService;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication(scanBasePackages = { "com.baeldung.activiti.security.config", "com.baeldung.activiti.security.withactiviti" })
public class SpringSecurityActivitiApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityActivitiApplication.class, args);
}
@Bean
InitializingBean usersAndGroupsInitializer(IdentityService identityService) {
return new InitializingBean() {
public void afterPropertiesSet() throws Exception {
User user = identityService.newUser("activiti_user");
user.setPassword("pass");
identityService.saveUser(user);
Group group = identityService.newGroup("user");
group.setName("ROLE_USER");
group.setType("USER");
identityService.saveGroup(group);
identityService.createMembership(user.getId(), group.getId());
}
};
}
}
@@ -0,0 +1,39 @@
package com.baeldung.activiti.security.withspring;
import org.activiti.engine.impl.persistence.entity.data.impl.MybatisGroupDataManager;
import org.activiti.engine.impl.persistence.entity.data.impl.MybatisUserDataManager;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.SecurityAutoConfiguration;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import com.baeldung.activiti.security.config.SpringSecurityGroupManager;
import com.baeldung.activiti.security.config.SpringSecurityUserManager;
@SpringBootApplication(exclude = SecurityAutoConfiguration.class, scanBasePackages = { "com.baeldung.activiti.security.config", "com.baeldung.activiti.security.withspring" })
public class ActivitiSpringSecurityApplication {
public static void main(String[] args) {
SpringApplication.run(ActivitiSpringSecurityApplication.class, args);
}
@Autowired
private SpringProcessEngineConfiguration processEngineConfiguration;
@Autowired
private JdbcUserDetailsManager userManager;
@Bean
InitializingBean processEngineInitializer() {
return new InitializingBean() {
public void afterPropertiesSet() throws Exception {
processEngineConfiguration.setUserEntityManager(new SpringSecurityUserManager(processEngineConfiguration, new MybatisUserDataManager(processEngineConfiguration), userManager));
processEngineConfiguration.setGroupEntityManager(new SpringSecurityGroupManager(processEngineConfiguration, new MybatisGroupDataManager(processEngineConfiguration)));
}
};
}
}
@@ -0,0 +1,50 @@
package com.baeldung.activiti.security.withspring;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/protected-process*")
.authenticated()
.anyRequest()
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/homepage")
.failureUrl("/login?error=true")
.and()
.csrf()
.disable()
.logout()
.logoutSuccessUrl("/login");
}
@Bean
public JdbcUserDetailsManager userDetailsManager() {
JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
manager.setDataSource(dataSource);
return manager;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsManager());
}
}
@@ -0,0 +1,52 @@
package com.baeldung.activitiwithspring;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
@RestController
public class ActivitiController {
private static final Logger logger = LoggerFactory.getLogger(ActivitiController.class);
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@GetMapping("/start-process")
public String startProcess() {
runtimeService.startProcessInstanceByKey("my-process");
return "Process started. Number of currently running process instances = " + runtimeService.createProcessInstanceQuery()
.count();
}
@GetMapping("/get-tasks/{processInstanceId}")
public List<TaskRepresentation> getTasks(@PathVariable String processInstanceId) {
List<Task> usertasks = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.list();
return usertasks.stream()
.map(task -> new TaskRepresentation(task.getId(), task.getName(), task.getProcessInstanceId()))
.collect(Collectors.toList());
}
@GetMapping("/complete-task-A/{processInstanceId}")
public void completeTaskA(@PathVariable String processInstanceId) {
Task task = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.singleResult();
taskService.complete(task.getId());
logger.info("Task completed");
}
}
@@ -0,0 +1,12 @@
package com.baeldung.activitiwithspring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class ActivitiWithSpringApplication {
public static void main(String[] args) {
SpringApplication.run(ActivitiWithSpringApplication.class, args);
}
}
@@ -0,0 +1,43 @@
package com.baeldung.activitiwithspring;
class TaskRepresentation {
private String id;
private String name;
private String processInstanceId;
public TaskRepresentation() {
super();
}
public TaskRepresentation(String id, String name, String processInstanceId) {
this.id = id;
this.name = name;
this.processInstanceId = processInstanceId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProcessInstanceId() {
return processInstanceId;
}
public void setProcessInstanceId(String processInstanceId) {
this.processInstanceId = processInstanceId;
}
}
@@ -0,0 +1,12 @@
package com.baeldung.activitiwithspring.servicetasks;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
public class SendEmailServiceTask implements JavaDelegate {
public void execute(DelegateExecution execution) {
//logic to sent email confirmation
}
}
@@ -0,0 +1,3 @@
insert into users(username, password, enabled) values ('spring_user', 'pass', true);
insert into authorities(username, authority) values ('spring_user','ROLE_USER');
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,36 @@
<?xml version='1.0' encoding='UTF-8'?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef" xmlns:modeler="http://activiti.com/modeler" modeler:version="1.0ev" modeler:exportDateTime="20170726123124" modeler:modelId="1005315" modeler:modelVersion="1" modeler:modelLastUpdated="1501068675875">
<process id="my-process" name="say-hello-process" isExecutable="true">
<startEvent id="startEvent" name="startEvent">
</startEvent>
<sequenceFlow id="sequence-flow-1" sourceRef="startEvent" targetRef="A">
</sequenceFlow>
<userTask id="A" name="A" activiti:assignee="$INITIATOR">
</userTask>
<sequenceFlow id="sequence-flow-2" sourceRef="A" targetRef="endEvent">
</sequenceFlow>
<endEvent id="endEvent" name="endEvent">
</endEvent>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_say-hello-process">
<bpmndi:BPMNPlane bpmnElement="say-hello-process" id="BPMNPlane_say-hello-process">
<bpmndi:BPMNShape bpmnElement="startEvent" id="BPMNShape_startEvent">
<omgdc:Bounds height="30.0" width="30.0" x="120.0" y="163.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endEvent" id="BPMNShape_endEvent">
<omgdc:Bounds height="28.0" width="28.0" x="365.0" y="164.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="A" id="BPMNShape_A">
<omgdc:Bounds height="80.0" width="100.0" x="210.0" y="138.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequence-flow-1" id="BPMNEdge_sequence-flow-1">
<omgdi:waypoint x="150.0" y="178.0"/>
<omgdi:waypoint x="210.0" y="178.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequence-flow-2" id="BPMNEdge_sequence-flow-2">
<omgdi:waypoint x="310.0" y="178.0"/>
<omgdi:waypoint x="365.0" y="178.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
@@ -0,0 +1,41 @@
<?xml version='1.0' encoding='UTF-8'?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef" xmlns:modeler="http://activiti.com/modeler" modeler:version="1.0ev" modeler:exportDateTime="20170726123124" modeler:modelId="1005315" modeler:modelVersion="1" modeler:modelLastUpdated="1501068675875">
<process id="protected-process" name="protected-process" isExecutable="true">
<startEvent id="startEvent" name="startEvent">
</startEvent>
<sequenceFlow id="sequence-flow-1" sourceRef="startEvent" targetRef="A">
</sequenceFlow>
<userTask id="A" name="A">
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>ROLE_USER</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<sequenceFlow id="sequence-flow-2" sourceRef="A" targetRef="endEvent">
</sequenceFlow>
<endEvent id="endEvent" name="endEvent">
</endEvent>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_protected-process">
<bpmndi:BPMNPlane bpmnElement="protected-process" id="BPMNPlane_protected-process">
<bpmndi:BPMNShape bpmnElement="startEvent" id="BPMNShape_startEvent">
<omgdc:Bounds height="30.0" width="30.0" x="120.0" y="163.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endEvent" id="BPMNShape_endEvent">
<omgdc:Bounds height="28.0" width="28.0" x="365.0" y="164.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="A" id="BPMNShape_A">
<omgdc:Bounds height="80.0" width="100.0" x="210.0" y="138.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequence-flow-1" id="BPMNEdge_sequence-flow-1">
<omgdi:waypoint x="150.0" y="178.0"/>
<omgdi:waypoint x="210.0" y="178.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequence-flow-2" id="BPMNEdge_sequence-flow-2">
<omgdi:waypoint x="310.0" y="178.0"/>
<omgdi:waypoint x="365.0" y="178.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
@@ -0,0 +1,3 @@
create table users(username varchar(255), password varchar(255), enabled boolean);
create table authorities(username varchar(255),authority varchar(255));
@@ -0,0 +1,21 @@
<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="login" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
</body>
</html>
@@ -0,0 +1,19 @@
package com.baeldung;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.activitiwithspring.ActivitiWithSpringApplication;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ActivitiWithSpringApplication.class)
@AutoConfigureTestDatabase
public class SpringContextIntegrationTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}
@@ -0,0 +1,19 @@
package com.baeldung;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.activitiwithspring.ActivitiWithSpringApplication;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ActivitiWithSpringApplication.class)
@AutoConfigureTestDatabase
public class SpringContextTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}
@@ -0,0 +1,118 @@
package com.baeldung.activitiwithspring;
import com.baeldung.activitiwithspring.TaskRepresentation;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringBootTest
public class ActivitiControllerIntegrationTest {
private static final Logger logger = LoggerFactory.getLogger(ActivitiControllerIntegrationTest.class);
private MockMvc mockMvc;
@Autowired
private WebApplicationContext wac;
@Autowired
RuntimeService runtimeService;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
.build();
for (ProcessInstance instance : runtimeService.createProcessInstanceQuery()
.list()) {
runtimeService.deleteProcessInstance(instance.getId(), "Reset Processes");
}
}
@Test
public void givenProcess_whenStartProcess_thenIncreaseInProcessInstanceCount() throws Exception {
String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/start-process"))
.andReturn()
.getResponse()
.getContentAsString();
assertEquals("Process started. Number of currently running process instances = 1", responseBody);
responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/start-process"))
.andReturn()
.getResponse()
.getContentAsString();
assertEquals("Process started. Number of currently running process instances = 2", responseBody);
responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/start-process"))
.andReturn()
.getResponse()
.getContentAsString();
assertEquals("Process started. Number of currently running process instances = 3", responseBody);
}
@Test
public void givenProcess_whenProcessInstance_thenReceivedRunningTask() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/start-process"))
.andReturn()
.getResponse();
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
.orderByProcessInstanceId()
.desc()
.list()
.get(0);
logger.info("process instance = " + pi.getId());
String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/get-tasks/" + pi.getId()))
.andReturn()
.getResponse()
.getContentAsString();
ObjectMapper mapper = new ObjectMapper();
List<TaskRepresentation> tasks = Arrays.asList(mapper.readValue(responseBody, TaskRepresentation[].class));
assertEquals(1, tasks.size());
assertEquals("A", tasks.get(0).getName());
}
@Test
public void givenProcess_whenCompleteTaskA_thenReceivedNextTask() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/start-process"))
.andReturn()
.getResponse();
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
.orderByProcessInstanceId()
.desc()
.list()
.get(0);
logger.info("process instance = " + pi.getId());
this.mockMvc.perform(MockMvcRequestBuilders.get("/complete-task-A/" + pi.getId()))
.andReturn()
.getResponse()
.getContentAsString();
List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().list();
assertEquals(0, list.size());
}
}
@@ -0,0 +1,33 @@
package com.baeldung.activitiwithspring;
import org.activiti.engine.IdentityService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.baeldung.activiti.security.withspring.ActivitiSpringSecurityApplication;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ActivitiSpringSecurityApplication.class)
@WebAppConfiguration
@AutoConfigureTestDatabase
public class ActivitiSpringSecurityIntegrationTest {
@Autowired
private IdentityService identityService;
@Test
public void whenUserExists_thenOk() {
identityService.setUserPicture("spring_user", null);
}
@Test(expected = UsernameNotFoundException.class)
public void whenUserNonExistent_thenSpringException() {
identityService.setUserPicture("user3", null);
}
}
@@ -0,0 +1,18 @@
package com.baeldung.activitiwithspring;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ActivitiWithSpringApplication.class)
@AutoConfigureTestDatabase
public class ActivitiWithSpringApplicationIntegrationTest {
@Test
public void contextLoads() {
}
}
@@ -0,0 +1,70 @@
package com.baeldung.activitiwithspring;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.junit.Test;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class ProcessEngineCreationIntegrationTest {
@Test
public void givenXMLConfig_whenGetDefault_thenGotProcessEngine() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
assertNotNull(processEngine);
assertEquals("root", processEngine.getProcessEngineConfiguration().getJdbcUsername());
}
@Test
public void givenXMLConfig_whenCreateDefaultConfiguration_thenGotProcessEngine() {
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
assertNotNull(processEngine);
assertEquals("root", processEngine.getProcessEngineConfiguration().getJdbcUsername());
}
@Test
public void givenDifferentNameXMLConfig_whenGetProcessEngineConfig_thenGotResult() {
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("my.activiti.cfg.xml");
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
assertNotNull(processEngine);
assertEquals("baeldung", processEngine.getProcessEngineConfiguration().getJdbcUsername());
}
@Test
public void givenDifferentBeanNameInXMLConfig_whenGetProcessEngineConfig_thenGotResult() {
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource("my.activiti.cfg.xml", "myProcessEngineConfiguration");
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
assertNotNull(processEngine);
assertEquals("baeldung", processEngine.getProcessEngineConfiguration().getJdbcUsername());
}
@Test
public void givenNoXMLConfig_whenCreateInMemProcessEngineConfig_thenCreated() {
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
ProcessEngine processEngine = processEngineConfiguration
.setJdbcUrl("jdbc:h2:mem:my-own-in-mem-db;DB_CLOSE_DELAY=1000")
.buildProcessEngine();
assertNotNull(processEngine);
assertEquals("sa", processEngine.getProcessEngineConfiguration().getJdbcUsername());
}
@Test
public void givenNoXMLConfig_whenCreateProcessEngineConfig_thenCreated() {
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
ProcessEngine processEngine = processEngineConfiguration
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE)
.setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
.buildProcessEngine();
assertNotNull(processEngine);
assertEquals("sa", processEngine.getProcessEngineConfiguration().getJdbcUsername());
}
@After
public void cleanup() {
ProcessEngines.destroy();
}
}
@@ -0,0 +1,98 @@
package com.baeldung.activitiwithspring;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class ProcessExecutionIntegrationTest {
@Test
public void givenBPMN_whenDeployProcess_thenDeployed() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
.addClasspathResource("org/activiti/test/vacationRequest.bpmn20.xml")
.deploy();
Long count = repositoryService.createProcessDefinitionQuery().count();
assertTrue(count >= 1);
}
@Test
public void givenProcessDefinition_whenStartProcessInstance_thenProcessRunning() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
.addClasspathResource("org/activiti/test/vacationRequest.bpmn20.xml")
.deploy();
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("employeeName", "Kermit");
variables.put("numberOfDays", new Integer(4));
variables.put("vacationMotivation", "I'm really tired!");
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("vacationRequest", variables);
Long count = runtimeService.createProcessInstanceQuery().count();
assertTrue(count >= 1);
}
@Test
public void givenProcessInstance_whenCompleteTask_thenProcessExecutionContinues() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
.addClasspathResource("org/activiti/test/vacationRequest.bpmn20.xml")
.deploy();
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("employeeName", "Kermit");
variables.put("numberOfDays", new Integer(4));
variables.put("vacationMotivation", "I'm really tired!");
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("vacationRequest", variables);
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
Task task = tasks.get(0);
Map<String, Object> taskVariables = new HashMap<String, Object>();
taskVariables.put("vacationApproved", "false");
taskVariables.put("comments", "We have a tight deadline!");
taskService.complete(task.getId(), taskVariables);
Task currentTask = taskService.createTaskQuery().taskName("Modify vacation request").singleResult();
assertNotNull(currentTask);
}
@Test(expected = ActivitiException.class)
public void givenProcessDefinition_whenSuspend_thenNoProcessInstanceCreated() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
.addClasspathResource("org/activiti/test/vacationRequest.bpmn20.xml")
.deploy();
RuntimeService runtimeService = processEngine.getRuntimeService();
repositoryService.suspendProcessDefinitionByKey("vacationRequest");
runtimeService.startProcessInstanceByKey("vacationRequest");
}
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:baeldung;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="baeldung" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
<bean id="myProcessEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:baeldung;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="baeldung" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
@@ -0,0 +1,149 @@
<?xml version='1.0' encoding='UTF-8'?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef" xmlns:modeler="http://activiti.com/modeler" modeler:version="1.0ev" modeler:exportDateTime="20170708124328" modeler:modelId="1005826" modeler:modelVersion="1" modeler:modelLastUpdated="1499514116825">
<process id="vacationRequest" name="vacationRequest" isExecutable="true">
<startEvent id="startEvent" name="request" activiti:initiator="employeeName">
<extensionElements>
<activiti:formProperty id="numberOfDays" name="Number of days" type="long" required="true"/>
<activiti:formProperty id="startDate" name="Vacation start date (MM-dd-yyyy)" type="date" datePattern="MM-dd-yyyy hh:mm" required="true"/>
<activiti:formProperty id="reason" name="Reason for leave" type="string"/>
<modeler:editor-resource-id><![CDATA[startEvent1]]></modeler:editor-resource-id>
</extensionElements>
</startEvent>
<userTask id="handle_vacation_request" name="Handle Request for Vacation">
<documentation>${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${reason}).</documentation>
<extensionElements>
<activiti:formProperty id="vacationApproval" name="Do you approve this vacation request?" type="enum" required="true"/>
<activiti:formProperty id="comments" name="Comments from Manager" type="string"/>
<modeler:allow-send-email><![CDATA[true]]></modeler:allow-send-email>
<modeler:activiti-idm-initiator><![CDATA[true]]></modeler:activiti-idm-initiator>
<modeler:editor-resource-id><![CDATA[sid-B9AA8E66-2F11-45D0-A270-B052E1A9248E]]></modeler:editor-resource-id>
</extensionElements>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>management</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<exclusiveGateway id="sid-12A577AE-5227-4918-8DE1-DC077D70967C">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-12A577AE-5227-4918-8DE1-DC077D70967C]]></modeler:editor-resource-id>
</extensionElements>
</exclusiveGateway>
<userTask id="modify_vacation_request" name="Modify vacation request" activiti:assignee="$INITIATOR">
<documentation>Your manager has disapproved your vacation request for ${numberOfDays} days.
Reason: ${comments}</documentation>
<extensionElements>
<activiti:formProperty id="numberOfDays" name="Number of days" type="long" expression="${numberOfDays}" required="true"/>
<activiti:formProperty id="startDate" name="First day of vacation(MM-dd-yyyy)" type="date" expression="${startDate}" datePattern="MM-dd-yyyy hh:mm" required="true"/>
<activiti:formProperty id="reason" name="Reason for leave" type="string" expression="${reason}"/>
<activiti:formProperty id="resendRequest" name="Resend vacation request to manager?" type="enum" required="true"/>
<modeler:allow-send-email><![CDATA[true]]></modeler:allow-send-email>
<modeler:activiti-idm-initiator><![CDATA[true]]></modeler:activiti-idm-initiator>
<modeler:initiator-can-complete><![CDATA[false]]></modeler:initiator-can-complete>
<modeler:editor-resource-id><![CDATA[sid-47240E94-C0C1-4886-B856-BC8E757746C9]]></modeler:editor-resource-id>
</extensionElements>
</userTask>
<serviceTask id="send-email-confirmation" name="Send email confirmation" activiti:class="com.example.activitiwithspring.servicetasks.SendEmailServiceTask.java">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-2C5E1831-9101-4F70-9AEF-4BA72B704205]]></modeler:editor-resource-id>
</extensionElements>
</serviceTask>
<sequenceFlow id="flow1" name="flow1" sourceRef="startEvent" targetRef="handle_vacation_request">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-638FA42C-E698-4BC9-9EB3-265968CA4E93]]></modeler:editor-resource-id>
</extensionElements>
</sequenceFlow>
<sequenceFlow id="flow2" name="flow2" sourceRef="handle_vacation_request" targetRef="sid-12A577AE-5227-4918-8DE1-DC077D70967C">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-6F2DDE04-7618-4EEA-B7DC-5BD5E0036BE3]]></modeler:editor-resource-id>
</extensionElements>
</sequenceFlow>
<endEvent id="EndEvent" name="End Event">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-381E38DD-C43B-4D36-8BB1-4C96F4E90A5C]]></modeler:editor-resource-id>
</extensionElements>
</endEvent>
<sequenceFlow id="flow7" name="flow7" sourceRef="send-email-confirmation" targetRef="EndEvent">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-F059DECE-ADF0-4BFC-BCB5-1F670ECA2C1D]]></modeler:editor-resource-id>
</extensionElements>
</sequenceFlow>
<sequenceFlow id="flow3" name="approved" sourceRef="sid-12A577AE-5227-4918-8DE1-DC077D70967C" targetRef="send-email-confirmation">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-609BEB69-E833-4D2F-BD14-FC8F7FD3E9C7]]></modeler:editor-resource-id>
</extensionElements>
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${vacationApproved == 'true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4" name="rejected" sourceRef="sid-12A577AE-5227-4918-8DE1-DC077D70967C" targetRef="modify_vacation_request">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-C5D24BF7-A499-4B44-8670-F4D674475623]]></modeler:editor-resource-id>
</extensionElements>
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${vacationApproved == 'false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow6" name="Don't Resend" sourceRef="modify_vacation_request" targetRef="EndEvent">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-5E626939-310D-4A58-947E-B3AE0DCDEE58]]></modeler:editor-resource-id>
</extensionElements>
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${resendRequest == 'false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow5" name="Resend Request" sourceRef="modify_vacation_request" targetRef="handle_vacation_request">
<extensionElements>
<modeler:editor-resource-id><![CDATA[sid-F0B813CA-C242-4C33-861A-5EFDDAE0C66D]]></modeler:editor-resource-id>
</extensionElements>
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${resendRequest == 'true'}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_vacationRequest">
<bpmndi:BPMNPlane bpmnElement="vacationRequest" id="BPMNPlane_vacationRequest">
<bpmndi:BPMNShape bpmnElement="startEvent" id="BPMNShape_startEvent">
<omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="handle_vacation_request" id="BPMNShape_handle_vacation_request">
<omgdc:Bounds height="80.0" width="100.0" x="210.0" y="138.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-12A577AE-5227-4918-8DE1-DC077D70967C" id="BPMNShape_sid-12A577AE-5227-4918-8DE1-DC077D70967C">
<omgdc:Bounds height="40.0" width="40.0" x="375.0" y="158.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="modify_vacation_request" id="BPMNShape_modify_vacation_request">
<omgdc:Bounds height="80.0" width="100.0" x="465.0" y="225.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="send-email-confirmation" id="BPMNShape_send-email-confirmation">
<omgdc:Bounds height="80.0" width="100.0" x="465.0" y="105.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="EndEvent" id="BPMNShape_EndEvent">
<omgdc:Bounds height="28.0" width="28.0" x="660.0" y="180.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="130.0" y="178.0"/>
<omgdi:waypoint x="210.0" y="178.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="310.0" y="178.18450184501845"/>
<omgdi:waypoint x="375.4259259259259" y="178.42592592592592"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="411.12091503267976" y="174.12091503267973"/>
<omgdi:waypoint x="465.0" y="159.01673640167365"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="395.5" y="197.5"/>
<omgdi:waypoint x="395.5" y="265.0"/>
<omgdi:waypoint x="465.0" y="265.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="465.0" y="285.0"/>
<omgdi:waypoint x="259.75" y="285.0"/>
<omgdi:waypoint x="259.99632352941177" y="218.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="565.0" y="242.67295597484278"/>
<omgdi:waypoint x="661.2166041257227" y="199.70830884952008"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
<omgdi:waypoint x="565.0" y="145.0"/>
<omgdi:waypoint x="674.0" y="145.0"/>
<omgdi:waypoint x="674.0" y="180.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>