Uvod u Activiti s proljećem
1. Pregled
Jednostavno rečeno, Activiti je platforma za rad i upravljanje poslovnim procesima.
Možemo brzo započeti stvaranjem a ProcessEngineConfiguration (obično se temelji na konfiguracijskoj datoteci). Iz toga možemo dobiti a ProcessEngine - i kroz ProcessEngine, možemo izvršavati radne tokove i BPM operacije.
API pruža razne usluge koje se mogu koristiti za pristup procesima i upravljanje njima. Te usluge mogu nam pružiti informacije o povijesti procesa, onome što se trenutno izvodi i procesima koji su postavljeni, ali još uvijek nisu pokrenuti.
Usluge se također mogu koristiti za definiranje strukture procesa i manipuliranje stanjem procesa, tj. Pokretanje, obustavljanje, otkazivanje itd.
Ako ste novi u API-ju, pogledajte naš Uvod u Activiti API s Javom. U ovom ćemo članku razgovarati o tome kako možemo postaviti Activiti API u programu Spring Boot.
2. Postavljanje s Spring Boot
Pogledajmo kako možemo postaviti Activiti kao aplikaciju Spring Boot Maven i početi ga koristiti.
2.1. Početno postavljanje
Kao i obično, moramo dodati ovisnost o mavenu:
org.activiti activiti-spring-boot-starter-basic
Najnoviju stabilnu verziju API-ja možete pronaći ovdje. Radi s Spring Boot-om do verzije 1.5.4. Još ne radi s v2.0.0.M1.
Također možemo generirati projekt Spring Boot koristeći //start.spring.io i odabrati Activiti kao ovisnost.
Samo dodavanjem ove ovisnosti i @EnableAutoConfiguration napomena za Spring Boot Application, izvršit će početno postavljanje:
- Stvori izvor podataka (API zahtijeva bazu podataka za stvaranje datoteke ProcessEngine)
- Stvorite i izložite ProcessEngine grah
- Stvorite i izložite grah usluga Activiti
- Stvorite proljetnog izvršitelja posla
2.2. Stvaranje i pokretanje procesa
Izgradimo primjer stvaranja i vođenja poslovnog procesa.
Da bismo definirali postupak trebat ćemo stvoriti BPMN datoteku. Za to možemo koristiti //activiti.alfresco.com/activiti-app/editor za izradu definicije procesa.
Zatim samo preuzmite BPMN datoteku. Morat ćemo staviti ovu datoteku u src / glavni / resursi / procesi mapu. Prema zadanim postavkama, Spring Boot će pogledati u ovu mapu za postavljanje definicije procesa.
Stvorit ćemo demo postupak koji sadrži jedan korisnički zadatak:
Primatelj korisničkog zadatka postavljen je kao pokretač postupka. BPMN datoteka za ovu definiciju procesa izgleda ovako:
Sada ćemo stvoriti REST kontroler za obradu zahtjeva za pokretanje ovog postupka:
@Autowired private RuntimeService runtimeService; @GetMapping ("/ start-process") javni niz startProcess () {runtimeService.startProcessInstanceByKey ("my-process"); return "Proces je započet. Broj trenutno pokrenutih" + "instanci procesa =" + runtimeService.createProcessInstanceQuery (). count (); }
Ovdje, runtimeService.startProcessInstanceByKey (“moj-postupak”) započinje izvršavanje postupka čiji je ključ "Moj proces". runtimeService.createProcessInstanceQuery (). count () dobit će nam broj instanci procesa.
Svaki put kad krenemo putem "/ Start-proces", novi ProcessInstance će se stvoriti i vidjet ćemo prirast broja trenutno pokrenutih procesa.
JUnit test slučaj pokazuje nam ovo ponašanje:
@Test public void givenProcess_whenStartProcess_thenIncreaseInProcessInstanceCount () baca izuzetak {String responseBody = this.mockMvc .perform (MockMvcRequestBuilders.get ("/ start-process")) .andReturn (). GetResponse (). assertEquals ("Proces je započet. Broj trenutno pokrenutih" + "instanci procesa = 1", responseBody); responseBody = this.mockMvc .perform (MockMvcRequestBuilders.get ("/ start-process")) .andReturn (). getResponse (). getContentAsString (); assertEquals ("Proces je započet. Broj trenutno pokrenutih" + "instanci procesa = 2", responseBody); responseBody = this.mockMvc .perform (MockMvcRequestBuilders.get ("/ start-process")) .andReturn (). getResponse (). getContentAsString (); assertEquals ("Proces je pokrenut. Broj trenutno pokrenutih" + "instanci procesa = 3", responseBody); }
3. Igranje s procesima
Sad kad u Activitiju imamo pokrenut postupak pomoću Spring Boota, proširimo gornji primjer da pokažemo kako možemo pristupiti i manipulirati procesom.
3.1. Nabavite popis Zadaci za dato ProcessInstance
Imamo dva korisnička zadatka A i B. Kad započnemo postupak, pričekat će prvi zadatak A biti dovršen, a zatim će izvršiti zadatak B. Stvorimo metodu rukovatelja koja prihvaća zahtjeve za pregled zadataka povezanih s danim processInstance.
Predmeti, poput Zadatak, ne može se poslati kao odgovor izravno i stoga moramo stvoriti prilagođeni objekt i pretvoriti Zadatak našem prilagođenom objektu. Nazvat ćemo ovaj razred Predstavljanje zadatka:
klasa TaskRepresentation {private String id; privatni naziv niza; private String processInstanceId; // standardni konstruktori}
Metoda rukovatelja izgledat će ovako:
@GetMapping ("/ get-tasks / {processInstanceId}") javni popis getTasks (@PathVariable String processInstanceId) {List usertasks = taskService.createTaskQuery () .processInstanceId (processInstanceId) .list (); vratiti usertasks.stream () .map (zadatak -> nova TaskRepresentation (task.getId (), task.getName (), task.getProcessInstanceId ())) .collect (Collectors.toList ()); }
Ovdje, taskService.createTaskQuery (). processInstanceId (processInstanceId) .list () koristi TaskService i dobiva nam popis zadataka povezanih s danim processInstanceId. Vidimo da ćemo kad započnemo izvoditi proces koji smo stvorili, dobiti zadatak A podnošenjem zahtjeva za metodu koju smo upravo definirali:
@Test javna praznina givenProcess_whenProcessInstance_thenReceivedRunningTask () baca izuzetak {this.mockMvc.perform (MockMvcRequestBuilders.get ("/ start-process")) .andReturn () .getResponse (); ProcessInstance pi = runtimeService.createProcessInstanceQuery () .orderByProcessInstanceId () .desc () .list () .get (0); Niz responseBody = this.mockMvc .perform (MockMvcRequestBuilders.get ("/ get-zadaci /" + pi.getId ())) .andReturn () .getResponse () .getContentAsString (); Mapa ObjectMapper = novi ObjectMapper (); Popis zadataka = Arrays.asList (mapper .readValue (responseBody, TaskRepresentation []. Class)); assertEquals (1, tasks.size ()); assertEquals ("A", tasks.get (0) .getName ()); }
3.2. Dovršavanje a Zadatak
Sad ćemo vidjeti što će se dogoditi kad dovršimo zadatak A. Izrađujemo metodu rukovatelja koja će obrađivati zahtjeve za dovršavanje zadatka A za dato processInstance:
@GetMapping ("/ complete-task-A / {processInstanceId}") javna praznina completeTaskA (@PathVariable String processInstanceId) {Task task = taskService.createTaskQuery () .processInstanceId (processInstanceId) .singleResult (); taskService.complete (task.getId ()); }
taskService.createTaskQuery (). processInstanceId (processInstanceId) .singleResult () stvara upit za uslugu zadataka i daje nam zadatak zadanog processInstance. Ovo je Zadatak korisnika A. Sljedeći redak taskService.complete (task.getId) izvršava ovaj zadatak.
Dakle, sada je proces došao do kraja i RuntimeService ne sadrži nijedan ProcessInsistance. To možemo vidjeti pomoću JUnit test slučaja:
@Test javna praznina givenProcess_whenCompleteTaskA_thenNoProcessInstance () baca izuzetak {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 (); Lista popisa = runtimeService.createProcessInstanceQuery (). List (); assertEquals (0, list.size ()); }
Na ovaj način možemo koristiti usluge Activiti za rad s procesima.
4. Zaključak
U ovom smo članku prošli pregled korištenja Activiti API-ja s Spring Boot-om. Više informacija o API-ju možete pronaći u korisničkom priručniku. Također smo vidjeli kako stvoriti postupak i izvršiti razne operacije na njemu pomoću usluga Activiti.
Spring Boot olakšava upotrebu jer ne trebamo brinuti o stvaranju baze podataka, implementaciji procesa ili stvaranju ProcessEngine.
Imajte na umu da je integracija Activitija s Spring Boot-om još uvijek u eksperimentalnoj fazi i još ga ne podržava Spring Boot 2.
Kao i uvijek, implementacija svih primjera koje smo vidjeli može se naći na GitHubu.