Pengantar Activiti dengan Spring

1. Ikhtisar

Sederhananya, Activiti adalah alur kerja dan platform Manajemen Proses Bisnis.

Kita dapat memulai dengan cepat dengan membuat ProcessEngineConfiguration (biasanya berdasarkan file konfigurasi). Dari sini, kita dapat memperoleh ProcessEngine - dan melalui ProcessEngine, kita dapat menjalankan operasi alur kerja & BPM.

API menyediakan berbagai layanan yang dapat digunakan untuk mengakses dan mengelola proses. Layanan ini dapat memberi kami informasi tentang riwayat proses, apa yang sedang berjalan dan proses yang diterapkan tetapi belum berjalan.

Layanan juga dapat digunakan untuk menentukan struktur proses dan memanipulasi keadaan proses, yaitu menjalankan, menangguhkan, membatalkan, dll.

Jika Anda baru mengenal API, lihat Pengantar API Activiti dengan Java kami . Pada artikel ini, kita akan membahas bagaimana kita dapat mengatur Activiti API dalam aplikasi Spring Boot.

2. Setup Dengan Spring Boot

Mari kita lihat bagaimana kita dapat mengatur Activiti sebagai aplikasi Spring Boot Maven dan mulai menggunakannya.

2.1. Pengaturan awal

Seperti biasa, kita perlu menambahkan dependensi maven:

 org.activiti activiti-spring-boot-starter-basic 

Versi stabil terbaru dari API dapat ditemukan di sini. Ia bekerja dengan Spring Boot hingga v1.5.4. Ini belum bekerja dengan v2.0.0.M1.

Kami juga dapat membuat proyek Spring Boot menggunakan //start.spring.io dan memilih Activiti sebagai dependensi.

Hanya dengan menambahkan ketergantungan ini dan anotasi @EnableAutoConfiguration ke Aplikasi Spring Boot, itu akan melakukan penyiapan awal:

  • Buat Sumber Data (API memerlukan database untuk membuat ProcessEngine )
  • Buat dan Ekspos kacang ProcessEngine
  • Membuat dan Mengekspos kacang layanan Activiti
  • Buat Pelaksana Pekerjaan Musim Semi

2.2. Membuat dan Menjalankan Proses

Mari kita buat contoh membuat dan menjalankan proses bisnis.

Untuk menentukan proses kita perlu membuat file BPMN. Untuk ini, kita dapat menggunakan //activiti.alfresco.com/activiti-app/editor untuk membuat definisi proses.

Kemudian, tinggal unduh file BPMN. Kita perlu meletakkan file ini di folder src / main / resources / proses . Secara default, Spring Boot akan mencari di folder ini untuk menerapkan definisi proses.

Kami akan membuat proses demo yang berisi satu tugas pengguna:

Penerima tugas pengguna ditetapkan sebagai Inisiator proses. File BPMN untuk definisi proses ini terlihat seperti:

Sekarang, kita akan membuat pengontrol REST untuk menangani permintaan untuk memulai proses ini:

@Autowired private RuntimeService runtimeService; @GetMapping("/start-process") public String startProcess() { runtimeService.startProcessInstanceByKey("my-process"); return "Process started. Number of currently running" + "process instances = " + runtimeService.createProcessInstanceQuery().count(); }

Di sini, runtimeService.startProcessInstanceByKey ("proses-saya") memulai eksekusi proses yang kuncinya adalah "proses-saya" . runtimeService.createProcessInstanceQuery (). count () akan memberi kita jumlah instance proses.

Setiap kali kita mencapai jalur "/ start-process" , ProcessInstance baru akan dibuat dan kita akan melihat peningkatan jumlah proses yang sedang berjalan.

Kasus uji JUnit menunjukkan kepada kita perilaku ini:

@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); } 

3. Bermain Dengan Proses

Sekarang kita memiliki proses yang berjalan di Activiti menggunakan Spring Boot, mari kita memperluas contoh di atas untuk mendemonstrasikan bagaimana kita dapat mengakses dan memanipulasi proses tersebut.

3.1. Dapatkan Daftar Tugas untuk ProcessInstance yang Diberikan

Kami memiliki dua tugas-tugas pengguna A dan B . Ketika kita mulai proses, itu akan menunggu untuk pertama tugas A akan selesai dan kemudian akan melaksanakan tugas B . Mari buat metode handler yang menerima permintaan untuk melihat tugas yang terkait dengan processInstance tertentu .

Objek, seperti Task , tidak dapat dikirim sebagai respons secara langsung dan karenanya kita perlu membuat objek kustom dan mengonversi Task ke objek kustom kita. Kami akan memanggil kelas ini TaskRepresentation :

class TaskRepresentation { private String id; private String name; private String processInstanceId; // standard constructors }

Metode penangan akan terlihat seperti:

@GetMapping("/get-tasks/{processInstanceId}") public List getTasks( @PathVariable String processInstanceId) { List usertasks = taskService.createTaskQuery() .processInstanceId(processInstanceId) .list(); return usertasks.stream() .map(task -> new TaskRepresentation( task.getId(), task.getName(), task.getProcessInstanceId())) .collect(Collectors.toList()); } 

Di sini, taskService.createTaskQuery (). ProcessInstanceId (processInstanceId) .list () menggunakan TaskService dan memberi kami daftar tugas yang terkait dengan processInstanceId yang diberikan . Kita dapat melihat bahwa ketika kita mulai menjalankan proses yang kita buat, kita akan mendapatkan tugas A dengan membuat permintaan ke metode yang baru saja kita tentukan:

@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); String responseBody = this.mockMvc .perform(MockMvcRequestBuilders.get("/get-tasks/" + pi.getId())) .andReturn() .getResponse() .getContentAsString(); ObjectMapper mapper = new ObjectMapper(); List tasks = Arrays.asList(mapper .readValue(responseBody, TaskRepresentation[].class)); assertEquals(1, tasks.size()); assertEquals("A", tasks.get(0).getName()); }

3.2. Menyelesaikan Tugas

Sekarang, kita akan melihat apa yang terjadi ketika kita menyelesaikan tugas A . Kami menciptakan metode handler yang akan menangani permintaan untuk menyelesaikan tugas A untuk diberikan processInstance :

@GetMapping("/complete-task-A/{processInstanceId}") public void completeTaskA(@PathVariable String processInstanceId) { Task task = taskService.createTaskQuery() .processInstanceId(processInstanceId) .singleResult(); taskService.complete(task.getId()); }

taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult() creates a query on the task service and gives us the task of the given processInstance. This is the UserTask A. The next line taskService.complete(task.getId) completes this task.

Hence, now the process has reached the end and the RuntimeService doesn't contain any ProcessInstances. We can see this using the JUnit test case:

@Test public void givenProcess_whenCompleteTaskA_thenNoProcessInstance() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get("/start-process")) .andReturn() .getResponse(); ProcessInstance pi = runtimeService.createProcessInstanceQuery() .orderByProcessInstanceId() .desc() .list() .get(0); this.mockMvc.perform(MockMvcRequestBuilders.get("/complete-task-A/" + pi.getId())) .andReturn() .getResponse() .getContentAsString(); List list = runtimeService.createProcessInstanceQuery().list(); assertEquals(0, list.size()); }

This is how we can use Activiti services work with processes.

4. Conclusion

Pada artikel ini, kami membahas ikhtisar penggunaan API Activiti dengan Spring Boot . Informasi lebih lanjut tentang API dapat ditemukan di panduan pengguna. Kami juga melihat cara membuat proses dan menjalankan berbagai operasi di atasnya menggunakan layanan Activiti.

Spring Boot membuatnya mudah digunakan karena kami tidak perlu khawatir tentang pembuatan database, menerapkan proses, atau membuat ProcessEngine .

Perlu diingat integrasi Activiti dengan Spring Boot masih dalam tahap percobaan dan belum didukung oleh Spring Boot 2.

Seperti biasa, implementasi dari semua contoh yang kami lihat dapat ditemukan di GitHub.