Activiti framework (Java) - deskripsi aliran tugas XML (bpm) dan manajemennya. Di sini saya akan menjelaskan konsep dasar dasar dan cara membangun proses bisnis sederhana.
Konsep utama Activiti adalah proses dan tugas. Suatu proses adalah semua tugas yang saling berhubungan oleh aliran dan cabang yang diarahkan.
Saya akan menyentuh aspek-aspek tersebut:
- - Activiti dalam bentuk yang paling murni
- - Pengguna, Peran
- - Hubungkan SpringBoot
- - REST API
- - Pekerjaan dan Delegasi
Pergerakan arus berjalan dalam langkah-langkah dari tugas ke tugas, setiap langkah tersebut menghentikan sementara proses sambil menunggu input dan penyelesaian tugas, semua tindakan menengah disimpan dalam database.
Di mana, apa yang harus diambil, saya akan tunjukkan di bawah ini. Mari kita mulai dengan contoh sederhana - proses pengembangan program, yang terdiri dari penulisan kode dan pengujian. Di bawah ini adalah diagram proses.

Ini semua proses, memiliki ID, Nama, dan karakteristik lainnya.

Itu memiliki:
Awal proses, dua tugas "Kembangkan" dan "Uji", satu cabang (gateway) dan akhir proses. Dengan kata lain, semuanya terjadi seperti ini:
- memuat deskripsi bpm
- mulai prosesnya
- setelah memulai, kami langsung jatuh ke tugas Mengembangkan
- setelah eksekusi Develop, ia pergi ke pengujian dan sesuai dengan hasil pengujian, proses berakhir atau kembali lagi ke pengembangan.
Activiti terdiri dari serangkaian layanan
Inilah yang utama:
- RepositoryService: mengontrol pemuatan deskripsi proses
- RuntimeService: memulai proses
- TaskService: melakukan tugas
- FormService: akses ke variabel tugas
- HistoryService: akses ke riwayat proses
- IdentityService: Pengguna dan Peran
Activiti dalam bentuk paling murni
Tapi itu semua dimulai dengan konfigurasi dan file - activiti.cfg.xml.
Dari sini
ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml");
Jika Anda tidak menggunakan konfigurasi Anda, maka Activiti akan menyebarkan database dalam memori H2 itu sendiri, ini tidak cocok untuk saya, tetapi Oracle yang saya cintai penuh, ada opsi untuk menghubungkan database yang berbeda.
Ini konfigurasi saya
activiti.cfg.xml <?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:oracle:thin:@localhost:1521:xe" /> <property name="jdbcDriver" value="oracle.jdbc.driver.OracleDriver" /> <property name="jdbcUsername" value="BPM" /> <property name="jdbcPassword" value="1" /> <property name="databaseSchemaUpdate" value="false" /> <property name="asyncExecutorActivate" value="false" /> <property name="mailServerPort" value="5025" /> </bean> </beans>
Kami mengubah nilai dalam "nama properti = jdbc *" dan menghubungkan database lain
Struktur proyek

POM <?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> <groupId>DemoActiviti</groupId> <artifactId>DemoActiviti</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.activiti</groupId> <version>6.0.0</version> <artifactId>activiti-spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.4.1</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.example.DemoActiviti</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
Kehadiran plugin "maven-assembly-plugin" di POM akan memungkinkan Anda untuk membangun (paket) botol yang diluncurkan dengan dependensi dan dijalankan -
java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar
Driver jdbc untuk Oracle diinstal di repositori maven lokal
mvn install:install-file -Dfile={Path/to/your/ojdbc6.jar} -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar
log4j log4j.rootLogger=WARN, ACT log4j.appender.ACT=org.apache.log4j.ConsoleAppender log4j.appender.ACT.layout=org.apache.log4j.PatternLayout log4j.appender.ACT.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n
Untuk proses ini, kami mendefinisikan 4 tindakan: pemuatan bpm, awal proses, pengembangan, dan pengujian. Setiap tindakan akan memiliki parameter yang sesuai: menyebarkan, memulai, mengembangkan, menguji.
Kami mengambil skrip untuk basis data
mulai aktifada di folder \ activiti-6.0.0 \ activiti-6.0.0 \ database \ create - skrip untuk membuat database
Pengguna, Peran
Siapkan pengguna dan peran:
Identitas public class DemoActiviti { private static final String DEV_PROCESS = "devProcess"; public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); ProcessEngine processEngine = cfg.buildProcessEngine(); createIdentity(processEngine, "programmer", "programmers"); createIdentity(processEngine, "tester", "testers"); } public static void createIdentity(ProcessEngine processEngine, String userName, String userGroup) { IdentityService identityService = processEngine.getIdentityService(); String userId = userName + "Id"; if (identityService.createUserQuery().userId(userId).count() == 0) { User user = identityService.newUser(userName); user.setId(userId); user.setEmail(userName + "@gmail.com"); identityService.saveUser(user); System.out.println("user created success fully"); } String groupId = userGroup + "Id"; if (identityService.createGroupQuery().groupId(groupId).count() == 0) { Group group = identityService.newGroup(userGroup); group.setName(userGroup); group.setId(groupId); identityService.saveGroup(group); System.out.println("group created success fully"); } if (identityService.createGroupQuery().groupId(groupId).list().size() > 0) { identityService.createMembership(userId, groupId); System.out.println("user to group success fully"); } } }
Buat pengguna dan grup, pengembang dan penguji masing-masing.
Dalam database, semua tabel dibagi oleh layanan yang sesuai dan memiliki awalan
ACT_RE_ *: repositori.
ACT_RU_ *: runtime.
ACT_ID_ *: identitas.
ACT_HI _ *: sejarah
dan sebagainya
Setelah membuat pengguna dari, Anda dapat melihat di sini

Kami akan menugaskan tugas kami dalam deskripsi ke grup yang sesuai (CandidateGroup), misalnya, Mengembangkan tugas ke grup - programer

Dan hal pertama yang kita lakukan adalah menempatkannya di basis data "MyProcess.bpmn", jalankan program dengan perintah
deploy java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar deploy
selanjutnya, mulailah proses mulai
java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar start
Setelah delpoy dan memulai proses, entri yang sesuai akan muncul di database.
Repositori

Runtime tugas apa yang sedang dieksekusi

kepada siapa ditugaskan

Dalam kode tersebut, tampilannya seperti ini (kode lengkapnya ada di bawah):
menyebarkan deployment = repositoryService.createDeployment() .addClasspathResource("processes/MyProcess.bpmn").deploy()
mulai ProcessInstance myProcess = runtimeService.startProcessInstanceByKey(DEV_PROCESS);
berkembangSetelah itu, Anda dapat mulai menyelesaikan tugas pengembangan.
java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar develop
// tasks = taskService.createTaskQuery().taskCandidateGroup("programmers").list();
Dalam tugas Mengembangkan, satu variabel "masalah" didefinisikan

Setelah memproses variabel menggunakan FormService, tugas berjalan
for (Task task : tasks) { System.out.println("Task:" + task.getTaskDefinitionKey() + ", id=" + task.getId()); FormData formData = formService.getTaskFormData(task.getId()); Map<String, Object> variables = new HashMap<String, Object>();

Untuk tugas Mengembangkan, Anda diminta untuk memasukkan variabel.
Di tabel historis, Anda bisa melihat variabel dan nilai tugas, proses

Dengan demikian, proses setelah tugas Mengembangkan akan berhenti di situ, negara akan disimpan dalam database.
Secara umum, loop terlihat seperti ini:
Meminta tugas untuk pelaksana
tasks = taskService.createTaskQuery().taskCandidateGroup("...").list();
Definisi Variabel
Map<String, Object> variables = new HashMap<String, Object>(); ... variables.put("var_1", value);
Eksekusi tugas
taskService.complete(task.getId(), variables);
Memeriksa akhir proses
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(processInstance.getId()).singleResult(); if (processInstance != null && !processInstance.isEnded())
Setelah setiap eksekusi tugas, proses ditangguhkan sampai tugas baru selesai.
Jadi, setelah menjalankan Develop, mari kita beralih ke tugas Uji, di sini kita juga akan diminta untuk memasukkan variabel "devResult" - hasil pengembangan (itu tidak berhasil dengan benar, bahkan sebelum Tes dimulai, masukkan hasilnya), dan kemudian hasilnya akan bercabang atau berakhir (Ok) atau pengembangan lagi (Tidak), lihat diagram proses.

Dalam hal ini, pengembangan, dll. Jika sekarang Anda meminta tugas untuk pengembang, mereka akan melakukannya, tetapi untuk pengujian - tidak.
Kode program package com.example; import org.activiti.engine.*; import org.activiti.engine.form.FormData; import org.activiti.engine.form.FormProperty; import org.activiti.engine.repository.Deployment; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.lang3.StringUtils; import java.util.*; public class DemoActiviti { private static final String DEV_PROCESS = "devProcess"; public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); ProcessEngine processEngine = cfg.buildProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); String mode = StringUtils.EMPTY; if (args.length > 0) { mode = args[0]; } System.out.println("Processes mode: " + mode); Deployment deployment; if ("deploy".equals(mode)) { deployment = repositoryService.createDeployment() .addClasspathResource("processes/MyProcess.bpmn").deploy(); System.out.println("deploy process success"); System.exit(0); } else { List<Deployment> myProcesses = repositoryService.createDeploymentQuery() .processDefinitionKey(DEV_PROCESS).list(); deployment = myProcesses.get(myProcesses.size()-1); System.out.println("get process success:" + deployment.getId()); }
Hubungkan SpringBoot
Kami memodifikasi proyek menggunakan Spring
Tambahkan dependensi ke POM
POM dengan SpringBoot <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.1.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.activiti</groupId> <version>6.0.0</version> <artifactId>activiti-spring-boot-starter-integration</artifactId> </dependency> ....
Kelas DemoActiviti sekarang menjadi seperti itu
DemoActiviti - SpringBootApplication @SpringBootApplication @ImportResource("classpath:activiti.cfg.xml") public class DemoActiviti { public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); SpringApplication.run(DemoActiviti.class, args); } }
Saya menggunakan model campuran - ketika bagian kacang dijelaskan dalam konfigurasi xml (@ImportResource ("classpath: activiti.cfg.xml")), dan yang lainnya didefinisikan melalui anotasi.
activiti.cfg.xml - pegas <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" /> <property name="username" value="BPM" /> <property name="password" value="1" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="true" /> <property name="asyncExecutorActivate" value="false" /> </bean> </beans>
Sekarang Spring bertanggung jawab atas konfigurasi, itu bisa dilihat
bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"
Tambahkan pemrosesan baris perintah standar untuk SpringBoot sebagai komponen
Commandline @Component public class CommandLine implements CommandLineRunner { @Autowired private DemoService demoService; public void run(String... args) { if ("test".equals(args[0])) { demoService.startTest(); } else if ("develop".equals(args[0])) { demoService.startDevelop(); } } }
Yang akan memproses semua perintah itu, saya tidak akan mengimplementasikan semuanya, semuanya sederhana di sana, saya akan menunjukkan dua: menguji dan mengembangkan. Dan menambahkan layanan untuk memprosesnya
Layanan Demo @Service public class DemoService { @Autowired private TaskService taskService; @Autowired private FormService formService; public void startTest() { List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("testers").list(); if (tasks.isEmpty()) { System.out.println(" "); return; } processTasks(tasks); } public void startDevelop() { List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("develop").list(); if (tasks.isEmpty()) { System.out.println(" "); return; } processTasks(tasks); } private void processTasks(List<Task> tasks) { Scanner scanner = new Scanner(System.in); for (Task task : tasks) { ...... , }
Dalam komponen CommandLine Autowir, mereka memiliki layanan DemoService, dan di dalamnya layanan Spring Activiti sudah disiapkan
@Autowired private TaskService taskService;
Kami mengumpulkan, menjalankan seperti sebelumnya dari baris perintah.
Jika kami ingin menggunakan eksekusi tugas dari Web, maka kami menghubungkan REST API.
API SISA
SpringBoot akan menyediakan server Tomcat tertanam secara default, dan kemudian masalah teknis.
Di POM, seperti apa adanya, tambahkan ketergantungan web spring
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Kami menghapus komponen CommandLine, sekarang semuanya akan datang melalui URL melalui HTTP. Tambahkan RestController:
Restcontroller @RestController public class DemoRestController { @Autowired private DemoService demoService; @RequestMapping(value="/test", method= RequestMethod.GET, produces= {MediaType.APPLICATION_JSON_VALUE}) public List<String> startTest(@RequestParam String devResult) { List<String> strings = demoService.startTest(devResult); return strings; } @RequestMapping(value="/develop", method= RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE) public List<String> startDevelop(@RequestParam String issue) { List<String> strings = demoService.startDevelop(issue); return strings; } @RequestMapping(value="/start", method= RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE) public List<String> startProcess() { List<String> strings = demoService.startDevProcess(); return strings; } }
Kami menjalankan perintah yang sama, sedikit mengubah respons dari layanan DemoService, yang Autowire berada di controller.
Layanan Demo @Service public class DemoService { @Autowired private TaskService taskService; @Autowired private FormService formService; @Autowired private RuntimeService runtimeService; public List<String> startTest(String devResult) { List<String> results = new ArrayList<>(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("testers").list(); if (tasks.isEmpty()) { results.add("The tasks for testing are not"); return results; } Object issue = runtimeService.getVariables(tasks.get(0).getProcessInstanceId()).get("issue"); processTasks(tasks, devResult); results.add("Task N " + issue + " - tested, result=" + devResult); return results; } public List<String> startDevelop(String issue) { List<String> results = new ArrayList<>(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("programmers").list(); if (tasks.isEmpty()) { results.add("There are no development tasks"); return results; } processTasks(tasks, issue); Object mIssue = runtimeService.getVariables(tasks.get(0).getProcessInstanceId()).get("issue"); results.add("Task N " + mIssue + " - taken in the develop"); return results; } public List<String> startDevProcess() { List<String> results = new ArrayList<>(); ProcessInstance myProcess = runtimeService.startProcessInstanceByKey("devProcess"); results.add("The process is started #"+myProcess.getId()); return results; } private void processTasks(List<Task> tasks, String param) { for (Task task : tasks) { FormData formData = formService.getTaskFormData(task.getId()); Map<String, Object> variables = new HashMap<>();
pengujian menggunakan curl, berikut hasilnya:

Saya mengubah port untuk Tomcat ke 8081 di application.properties
server.port = 8081
Pekerjaan aktiviti
Activiti memiliki banyak desain, misalnya, meluncurkan tugas yang dijadwalkan adalah "TimerStartEvent". Agar Ayub mulai menjalankan dalam pengekangan, Anda harus menentukan
property name="asyncExecutorActivate" value="true"
(lihat activiti.cfg.xml), maka proses java akan tetap berjalan dan akan memeriksa jadwal dan menjalankan tugas.
Saya akan kembali ke proyek awal, di mana Activiti digunakan dalam bentuk yang paling murni.
Di kelas DemoActiviti saya akan meninggalkan dukungan hanya untuk dua perintah: deploy dan mulai saya akan membuat proses baru

Setelah dimulainya proses, ia akan pergi ke timer, yang menurut jadwal akan meluncurkan tugas "Mengembangkan". Timer akan memiliki jadwal - mulai setiap 10 detik, ekspresi cron - β0/10 * * * * *?β.

Mari kita gunakan proses baru seperti sebelumnya, lalu mulai prosesnya (mulai). Semua - tugas berjalan setiap 10 detik.
Sebagai tugas, komponen Activiti dipilih - ServiceTask, yang darinya Anda dapat menentukan sebagai implementasi kelas Java

DemoDelegate kelas public class DemoDelegate implements JavaDelegate { @Override public void execute(DelegateExecution execution) { Date now = new Date(); execution.setVariable("issue", now.toString()); System.out.println("job start="+now); } }
Pada tabel dalam database (pilih * dari ACT_RU_TIMER_JOB t) Anda dapat melihat

Aktivitas kerja, di bidang DUEDATE_ akan ada waktu untuk memulai berikutnya.
Variabel "masalah" dari Delegasi akan direkam dalam riwayat eksekusi
select * from ACT_HI_VARINST t

kode untuk DemoActiviti c Job public class DemoActiviti { private static final String DEV_PROCESS = "devProcessJob"; public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); ProcessEngine processEngine = cfg.buildProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); String mode = StringUtils.EMPTY; if (args.length > 0) { mode = args[0]; } System.out.println("Processes mode: " + mode); Deployment deployment; if ("deploy".equals(mode)) { deployment = repositoryService.createDeployment() .addClasspathResource("processes/MyProcessJob.bpmn").deploy(); System.out.println("deploy process success"); System.exit(0); } else { List<Deployment> myProcesses = repositoryService.createDeploymentQuery() .processDefinitionKey(DEV_PROCESS).list(); deployment = myProcesses.get(myProcesses.size()-1); System.out.println("get process success:" + deployment.getId()); }
Masih banyak yang tertinggal: Acara, Pendengar, JPA, dll., Mungkin saya akan kembali ke mereka.
Material
ActivitiDesainer gerhanadevProses bpmn <?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/test"> <process id="devProcess" name="Dev process" isExecutable="true"> <startEvent id="startevent1" name="Start" activiti:initiator="programmerId"></startEvent> <userTask id="develop" name="Develop" activiti:candidateGroups="programmers"> <extensionElements> <activiti:formProperty id="issue" name="issue" type="string" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="develop"></sequenceFlow> <userTask id="test" name="Test" activiti:candidateGroups="testers"> <extensionElements> <activiti:formProperty id="devResult" name="devResult" type="string" default="No" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow2" sourceRef="develop" targetRef="test"></sequenceFlow> <exclusiveGateway id="gateway" name="Exclusive Gateway" default="flowNo"></exclusiveGateway> <sequenceFlow id="flow3" sourceRef="test" targetRef="gateway"></sequenceFlow> <sequenceFlow id="flowOk" name="Ok" sourceRef="gateway" targetRef="endevent1"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${devResult == "Ok"}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flowNo" name="No" sourceRef="gateway" targetRef="develop"></sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> </process> </definitions>
devProcessJob bpmn <?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/test"> <process id="devProcessJob" name="Dev process Job" isExecutable="true"> <startEvent id="startevent" name="Start" activiti:initiator="programmerId"></startEvent> <sequenceFlow id="flow1" sourceRef="startevent" targetRef="timerstartevent"></sequenceFlow> <endEvent id="endevent" name="End"></endEvent> <startEvent id="timerstartevent" name="Timer start"> <extensionElements> <activiti:formProperty id="issue" name="issue" type="string"></activiti:formProperty> </extensionElements> <timerEventDefinition> <timeCycle>0/10 * * * * ?</timeCycle> </timerEventDefinition> </startEvent> <sequenceFlow id="flow2" sourceRef="timerstartevent" targetRef="servicetask1"></sequenceFlow> <sequenceFlow id="flow3" sourceRef="servicetask1" targetRef="endevent"></sequenceFlow> <serviceTask id="servicetask1" name="Develop" activiti:class="com.example.DemoDelegate"></serviceTask> </process> </definitions>