Panduan untuk Activiti dengan Java

1. Gambaran keseluruhan

Activiti API adalah aliran kerja dan sistem Pengurusan Proses Perniagaan. Kita dapat menentukan proses di dalamnya, melaksanakannya, dan memanipulasinya dengan cara yang berbeza menggunakan perkhidmatan yang disediakan oleh API. Ia memerlukan JDK 7+.

Pembangunan menggunakan API dapat dilakukan di IDE apa pun, tetapi untuk menggunakan Activiti Designer, kita memerlukan Eclipse.

Kita dapat menentukan proses di dalamnya menggunakan standard BPMN 2.0. Terdapat cara lain yang kurang popular - menggunakan kelas Java seperti StartEvent , EndEvent , UserTask , SequenceFlow , dll.

Sekiranya kita ingin menjalankan proses atau mengakses salah satu perkhidmatan, kita perlu membuat ProcessEngineConfiguration .

Kita boleh mendapatkan ProcessEngine menggunakan ProcessEngineConfiguration, dalam beberapa cara, yang akan kita bincangkan lebih lanjut dalam artikel ini . Melaluiyang ProcessEngine kita boleh melakukan operasi Aliran Kerja dan BPMN.

2. Pergantungan Maven

Untuk menggunakan API ini, kita harus memasukkan ketergantungan Activiti:

 org.activiti activiti-engine 

3. Membuat ProcessEngine

ProcessEngine di Activiti, biasanya dikonfigurasikan menggunakan fail XML, activiti.cfg.xml . Contoh fail konfigurasi ini adalah:

Sekarang kita dapat memperoleh ProcessEngine menggunakan kelas ProcessEngines :

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

Penyataan ini akan mencari activiti.cfg. fail xml di classpath, dan membina ProcessEngine berdasarkan konfigurasi dalam fail.

Contoh kod untuk fail konfigurasi menunjukkan bahawa ia hanyalah konfigurasi berasaskan Spring. Tetapi, ini tidak bermaksud bahawa kita hanya dapat menggunakan Activiti di persekitaran Spring. Keupayaan Spring hanya digunakan secara dalaman untuk membuat ProcessEngine .

Mari tulis kes ujian JUnit yang akan membuat ProcessEngine menggunakan fail konfigurasi seperti di atas:

@Test public void givenXMLConfig_whenGetDefault_thenGotProcessEngine() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); assertNotNull(processEngine); assertEquals("root", processEngine.getProcessEngineConfiguration() .getJdbcUsername()); } 

4. API dan Perkhidmatan Engine Processiti Activiti

Titik masuk interaksi dengan API adalah ProcessEngine . Melalui ProcessEngine, kita dapat mengakses pelbagai perkhidmatan yang menyediakan kaedah aliran kerja / BPMN. The ProcessEngine dan semua objek perkhidmatan ini adalah thread selamat.

Diambil dari //www.activiti.org/userguide/images/api.services.png

The ProcessEngines kelas akan mengimbas untuk activiti.cfg.xml dan activiti-context.xml fail. Seperti yang disebutkan sebelumnya, untuk semua fail activiti.cfg.xml , ProcessEngine akan dibuat dengan cara biasa.

Manakala, untuk semua fail activiti-context.xml , ia akan dibuat dengan cara Spring - Saya akan membuat Spring Application Context dan akan memperoleh ProcessEngine dari itu. Selama pelaksanaan suatu proses, semua langkah akan dikunjungi dalam urutan yang ditentukan dalam file BPMN.

Selama pelaksanaan suatu proses, semua langkah akan dikunjungi dalam urutan yang ditentukan dalam file BPMN.

4.1. Definisi Proses dan Terma Berkaitan

A ProcessDefinition mewakili proses perniagaan. Ia digunakan untuk menentukan struktur dan tingkah laku pelbagai langkah dalam proses tersebut. Menggunakan definisi proses bermaksud memuatkan definisi proses ke dalam pangkalan data Activiti.

Definisi proses kebanyakannya ditentukan oleh standard BPMN 2.0. Juga mungkin untuk menentukannya menggunakan kod Java. Semua syarat yang ditentukan dalam bahagian ini tersedia sebagai kelas Java juga.

Sebaik sahaja kita mula menjalankan definisi proses, ia boleh disebut sebagai proses

A ProcessInstance adalah salah satu pelaksanaan yang ProcessDefinition.

A StartEvent dikaitkan dengan setiap proses perniagaan. Ini menunjukkan titik masuk proses. Begitu juga, ada EndEvent yang menunjukkan akhir proses. Kita dapat menentukan keadaan di atas peristiwa-peristiwa ini.

Semua langkah (atau elemen) di antara permulaan dan akhir disebut sebagai Tugas . Tugas boleh terdiri dari pelbagai jenis. Tugas yang paling kerap digunakan adalah UserTasks dan ServiceTasks .

UserTasks , seperti namanya, sedemikian rupa sehingga harus dilakukan secara manual oleh pengguna.

ServiceTasks , sebaliknya, dikonfigurasi dengan sekeping kod. Setiap kali pelaksanaan dijalankan, blok kod mereka akan dijalankan.

SequenceFlows menghubungkan Tugas . Kita dapat menentukan SequenceFlows dengan sumber dan elemen sasaran yang akan mereka sambungkan. Sekali lagi, kita juga dapat menentukan keadaan di atas SequenceFlows untuk membuat jalan bersyarat dalam proses tersebut.

4.2. Perkhidmatan

Kami akan membincangkan secara ringkas perkhidmatan yang diberikan oleh Activiti:

  • RepositoryService membantu kita memanipulasi penggunaan definisi proses. Perkhidmatan ini berkaitan dengan data statik yang berkaitan dengan definisi proses
  • RuntimeService menguruskan ProcessInstances (sedang berjalan proses) serta pemboleh ubah proses
  • TaskService memantau UserTasks . The Tugas yang perlu dilakukan secara manual oleh pengguna adalah teras API Activiti ini. Kita boleh membuat tugas, menuntut dan menyelesaikan tugas, memanipulasi penerima tugas, dll menggunakan perkhidmatan ini
  • FormService adalah perkhidmatan pilihan. API boleh digunakan tanpanya, dan tanpa mengorbankan salah satu ciri-cirinya. Ia digunakan untuk menentukan bentuk permulaan dan bentuk tugas dalam suatu proses.
  • Perkhidmatan Identiti menguruskan Pengguna dan Kumpulan
  • HistoryService melacak sejarah Activiti Engine. Kita juga boleh menetapkan tahap sejarah yang berbeza.
  • ManagementService berkaitan dengan metadata dan biasanya tidak diperlukan semasa membuat aplikasi
  • DynamicBpmnService menolong kita mengubah apa sahaja dalam proses tanpa menyebarkannya semula

5. Bekerja Dengan Perkhidmatan Activiti

Untuk mengetahui bagaimana kita dapat bekerja dengan perkhidmatan yang berbeda dan menjalankan proses, mari kita ambil contoh proses untuk "Permintaan percutian karyawan":

Fail BPMN 2.0, VacationRequest.bpmn20.xml , untuk proses ini akan mempunyai acara permulaan yang ditakrifkan sebagai:

Begitu juga, tugas pengguna pertama, yang diberikan kepada kumpulan pengguna "pengurusan", akan kelihatan seperti ini:

 ${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${reason}).       management   

Dengan ServiceTask, kita perlu menentukan bahagian kod yang akan dijalankan. Kami mempunyai sekeping kod ini sebagai kelas Java:

Aliran bersyarat akan ditunjukkan dengan menambahkan tag "conditionExpression" dalam "urutanFlow":

Di sini, vacationApproved adalah formProperty of UserTask yang ditunjukkan di atas.

Seperti yang dapat kita lihat dalam rajah, ini adalah proses yang sangat mudah. Pekerja membuat permintaan percutian, memberikan jumlah hari dan tarikh mula bercuti. Permintaan itu disampaikan kepada pengurus. Mereka boleh menyetujui / menolak permintaan tersebut.

Sekiranya diluluskan, ada tugas Perkhidmatan yang ditentukan untuk menghantar e-mel pengesahan. Sekiranya tidak disetujui, Karyawan dapat memilih untuk mengubah dan mengirim ulang permintaan, atau tidak melakukan apa-apa.

Tugas perkhidmatan disediakan dengan beberapa kod untuk dilaksanakan (di sini, sebagai kelas Java). Kami telah memberikan kelas SendEmailServiceTask.java.

These types of classes should extend the JavaDelegate. Also, we need to override its execute() method, which will be performed when the process execution reaches this step.

5.1. Deploying a Process

To make our process known to the Activiti Engine, we need to deploy the process. We can do it programmatically using the RepositoryService. Let's write a JUnit test to show this:

@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(); assertEquals("1", count.toString()); }

Deployment means that the engine will parse the BPMN file and convert it into something executable. Also, a record will be added to the Repository table for every deployment.

Hence, afterward, we can query the Repository service to get the deployed processes; the ProcessDefinitions.

5.2. Starting a ProcessInstance

After deploying the ProcessDefinition to Activiti Engine, we can execute the process by creating ProcessInstances. The ProcessDefinition is a blueprint, and the ProcessInstance is the runtime execution of it.

For a single ProcessDefinition, there can be multiple ProcessInstances.

All the details related to the ProcessInstances can be accessed through the RuntimeService.

In our example, at the start event, we need to pass the number of vacation days, the start date, and the reason. We will use the process variables, and pass them while creating the ProcessInstance.

Let's write a JUnit test case to get a better idea:

@Test public void givenDeployedProcess_whenStartProcessInstance_thenRunning() { //deploy the process definition Map variables = new HashMap>(); variables.put("employeeName", "John"); variables.put("numberOfDays", 4); variables.put("vacationMotivation", "I need a break!"); RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService .startProcessInstanceByKey("vacationRequest", variables); Long count=runtimeService.createProcessInstanceQuery().count(); assertEquals("1", count.toString()); }

The multiple instances of a single process definition will differ by the process variables.

There are multiple ways to start a process instance. Here, we are using the key of the process. After starting the process instance, we can get the information about it by querying the RuntimeService.

5.3. Completing Tasks

When our process instance starts running, the first step is a user task, assigned to the user group “management”.

The user might have an inbox that would have a list of tasks to be done by them. Now, if we want to continue the process execution, the user needs to finish this task. For Activiti Engine, it's called “completing the task”.

We can query the TaskService, to get the task object and then complete it.

The code we need to write for this looks like:

@Test public void givenProcessInstance_whenCompleteTask_thenGotNextTask() { // deploy process and start process instance TaskService taskService = processEngine.getTaskService(); List tasks = taskService.createTaskQuery() .taskCandidateGroup("management").list(); Task task = tasks.get(0); Map taskVariables = new HashMap(); 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); }

Note that the complete() method of TaskService also takes in the required process variables. We pass in the reply from the manager.

After this, the process engine will continue to the next step. Here, the next step asks the employee if the vacation request is to be re-sent or not.

So, our ProcessInstance is now waiting at this UserTask, which has the name “Modify vacation request”.

5.4. Suspending and Activating a Process

We can suspend a ProcessDefinition and also a ProcessInstance. If we suspend a ProcessDefinition, we cannot create an instance of it while it is suspended. We can do this using the RepositoryService:

@Test(expected = ActivitiException.class) public void givenDeployedProcess_whenSuspend_thenNoProcessInstance() { // deploy the process definition repositoryService.suspendProcessDefinitionByKey("vacationRequest"); runtimeService.startProcessInstanceByKey("vacationRequest"); } 

Untuk mengaktifkannya semula, kita hanya perlu memanggil salah satu kaedah repositoriService.activateProcessDefinitionXXX .

Begitu juga, kita dapat menangguhkan ProcessInstance, menggunakan RuntimeService.

6. Kesimpulannya

Dalam artikel ini, kami melihat bagaimana kami dapat menggunakan Activiti dengan Java. Kami membuat contoh fail ProcessEngineCofiguration , yang membantu kami membuat ProcessEngine .

Menggunakannya, kami mengakses pelbagai perkhidmatan yang disediakan oleh API. Perkhidmatan ini membantu kami mengurus dan mengawasi ProsesDefinisi , ProsesInstansi , Tugas Pengguna , dll.

Seperti biasa, kod contoh yang kita lihat dalam artikel terletak di GitHub.