Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

pl:dydaktyka:bim:lab4 [2013/11/18 16:45]
kkluza [Service task Get available hours używający funkcji klasy w Javie]
pl:dydaktyka:bim:lab4 [2019/06/27 15:50]
Linia 1: Linia 1:
-====== Lab 4: Service task w modelu BPMN ====== 
- 
-Na początek w eclipsie proszę stworzyć nowy fragment modelu, tak by łatwo można było go testować. ​ 
-Fragment ten będzie mógł zostać dołączony potem do naszego modelu z poprzednich zajęć. ​ 
- 
-{{  :​pl:​dydaktyka:​bim:​lab4:​eclipse3-process0.png ​ |}} 
- 
-Nasz model będzie się składał z podprocesu, którego zadaniem jest dokonać ewaluacji merytorycznej oferty. 
-Podprocesy są użyteczne, gdyż: 
-  - pozwalają na hierarchiczne modelowanie (w wielu narzędziach można wyświetlać podprocesy w postaci zwiniętej, nie ukazującej ich wewnętrznej logiki, dzięki czemu widzimy tylko model wysokiego poziomu), 
-  - tworzą nową przestrzeń dla zdarzeń, tzn. zdarzenia rzucane przy wykonywaniu podprocesu mogą być przechwytywane przez zdarzenia brzegowe podprocesu (a widoczność jest ograniczona do podprocesu). 
- 
-Istotne: W Activiti podproces musi się zaczynać pojedynczym zdarzeniem startowym i kończyć co najmniej jednym zdarzeniem końcowym, mimo że specyfikacja BPMN 2.0 pozwala omijać zdarzenia początkowe i końcowe w podprocesach. 
- 
-==== Service task "Get available hours" używający funkcji klasy w Javie ====  
- 
-Na początek poznamy możliwości uruchomienia określonej funkcji w Javie (z dołączonej klasy). 
- 
-Ogólnie service task wywołujący określoną funkcję w kodzie XML procesu wygląda następująco:​ 
- 
-<code xml><​serviceTask id="​javaService"​ name="​My Java Service Task" activiti:​expression="#​{object.function()}"​ /></​code>​ 
- 
-{{  :​pl:​dydaktyka:​bim:​lab4:​eclipse3-add-library-ts.png?​440|}} 
-W naszym przypadku będziemy chcieli zasymulować pobranie liczby dostępnych osobogodzin z zewnętrznego systemu. 
-W tym celu udostępniona została biblioteka z klasą ''​TeamSchedule''​ naśladującą takie zachowanie: {{:​pl:​dydaktyka:​bim:​lab4:​team-scheduler.jar|}}. ​ 
-Biblioteka ta zwraca dostępną liczbę osobogodzin (de facto funkcja ''​getAvailableHours()''​ zwraca losowo liczby: 14, 47, 78, zaś funkcja ''​getAvailableHours(int priority)''​ zwraca konkretną z liczb w zależności od znaku podanego argumentu). ​ 
-Dodajemy bibliotekę do naszego projektu w miejscu ''/​src/​test/​resources/​lib/''​. ​ 
-Działanie naszego Team Schedulera można przetestować przy użyciu testu ''​TeamScheduleTest'',​ który sprawdza 2 dostępne funkcje klasy ''​TeamSchedule'':​ 
- 
-<code java TeamScheduleTest.java>​ 
-package pl.org.bpmn;​ 
-import static org.junit.Assert.assertEquals;​ 
-import static org.junit.Assert.assertTrue;​ 
-import java.util.Arrays;​ 
-import pl.org.bpmn.TeamSchedule;​ 
-import org.junit.Test;​ 
- 
-public class TeamScheduleTest { 
-  
- @Test 
- public void testAvailableHours(){ 
- TeamSchedule schedule = new TeamSchedule();​  
- for(int i=0; i<10; i++) { 
- int avHrs = schedule.getAvailableHours();​ 
- assertTrue(Arrays.asList(14,​ 47, 78).contains(avHrs));​ 
- }  
- } 
-  
- @Test 
- public void testAvailableHoursWithPriority(){ 
- TeamSchedule schedule = new TeamSchedule();​  
- assertEquals(schedule.getAvailableHours(-10),​ 14);  
- assertEquals(schedule.getAvailableHours(0),​ 47);  
- assertEquals(schedule.getAvailableHours(10),​ 78);  
- } 
- 
-}</​code>​ 
- 
- 
-Ponieważ chcemy mieć dostęp do obiektu klasy ''​TeamSchedule'',​ potrzebujemy go stworzyć przy uruchamianiu silnika activiti. W tym celu w pliku konfiguracyjnym w projekcie (np. ''​activiti.cfg-mem.xml''​),​ dodajemy odpowiednią linijkę: 
- 
-<code xml><​bean id="​schedule"​ class="​pl.org.bpmn.TeamSchedule"/></​code>​ 
- 
-Teraz możemy już w eclipsowym Activiti Designerze dodać odpowiednie wywołanie: 
- 
-{{:​pl:​dydaktyka:​bim:​lab4:​eclipse3-java-expression.png?​600 ​ |}} 
- 
-==== Testowanie modelu ==== 
- 
-Aby uprościć testowanie modelu skorzystamy z klasy ''​[[http://​www.activiti.org/​javadocs/​org/​activiti/​engine/​test/​ActivitiRule.html|Activiti Rule]]'',​ która służy do inicjalizacji silnika procesowego dla JUnit testów. ​ 
- 
-Proszę dodać poniższy plik do projektu: 
- 
-<code java CheckOfferTest.java>​ 
-package pl.org.bpmn;​ 
- 
-import java.util.List;​ 
-import org.activiti.engine.*;​ 
-import org.activiti.engine.runtime.ProcessInstance;​ 
-import org.activiti.engine.task.Task;​ 
-import org.activiti.engine.test.ActivitiRule;​ 
-import org.activiti.engine.test.Deployment;​ 
-import org.junit.*;​ 
- 
-public class CheckOfferTest { 
-  
- @Rule ​ 
- public ActivitiRule activitiRule = new ActivitiRule("​activiti.cfg-mem.xml"​);​ 
-  
- @Test 
- @Deployment(resources={"​diagrams/​CheckOffer.bpmn20.xml"​}) 
- public void executeJavaExpression() { 
- RuntimeService runtimeService = activitiRule.getRuntimeService();​ 
- TaskService taskService = activitiRule.getTaskService();​ 
- ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("​process-key"​);​ 
- List<​Task>​ taskList; 
- do { 
- taskList = taskService.createTaskQuery() 
-       .processInstanceId(processInstance.getId()).list();​ 
- if(taskList.size()!=0) { 
- System.out.println("​Completing task: " + taskList.get(0).getName());​ 
- taskService.complete(taskList.get(0).getId());​ 
- } 
- } while(taskList.size()!=0);​ 
- } 
-} 
-</​code>​ 
- 
-W pliku konfiguracyjnym w projekcie (''​activiti.cfg-mem.xml''​) należy jeszcze dodać odpowiednią linijkę do połączenia z serwerem: 
-<code xml> 
-  <bean id="​processEngineConfiguration"​ 
-        class="​org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">​  
-    <​property name="​jdbcUrl"​ value="​jdbc:​h2:​tcp://​localhost/​activiti"​ /> 
-    <​property name="​jdbcDriver"​ value="​org.h2.Driver"​ /> 
-    <​property name="​jdbcUsername"​ value="​sa"​ /> 
-    <​property name="​jdbcPassword"​ value=""​ /> 
-  </​bean>​ 
-</​code>​ 
- 
-W powyższym kodzie plik konfiguracyjny uruchamia silnik procesowy w trybie //​StandaloneInMemProcessEngineConfiguration//​. Jest to tryb wygodny do testów jednostkowych,​ gdyż w tym trybie baza danych zostanie utworzona w trakcie uruchamiania silnika i następnie skasowana przy wyłączaniu. ​ 
- 
-** Sprawdzenie zmiennych procesu **  
- 
-Proszę rozbudować powyższy test, tak aby wyświetlał zmienną zwracaną do procesu przez zadanie **Get available hours** i testował jej wartość, analogicznie jak to miało miejsce przy testowaniu klasy ''​TeamSchedule''​. 
- 
-DO SPRAWOZDANIA:​ 
-  * Proszę w sprawozdaniu umieścić model oraz rozbudowany test. 
- 
-==== Rozbudowa modelu o logikę niskopoziomową w Javie ==== 
- 
-Zanim wprowadzimy nową klasę Javy do ewaluacji merytorycznej (na kolejnych zajęciach częściowo zostanie to zastąpione regułami), potrzebujemy mieć wartości zmiennych, będących potencjalnymi czynniki analizy merytorycznej. 
- 
-Dla klasy **Set offer factors** ustawiamy więc 3 zmienne (potencjalne czynniki analizy merytorycznej): ​ 
-  * **Project Attractiveness** -- atrakcyjność merytoryczna zamówienia. ​ 
-  * **Required Hours** -- przewidywana liczba osobogodzin do wykonania projektu opisanego w ofercie. ​ 
-  * **Team Skills** -- określa poziom kompetencji potencjalnego zespołu do wykonania projektu. 
- 
-{{  :​pl:​dydaktyka:​bim:​lab4:​eclipse3-factor-parameters.png ​ |}} 
- 
-Proszę wprowadzić stosowne zmiany do jUnit testu, by wczytać 3 dowolne wartości do powyższych zmiennych. 
- 
-Następnie będziemy chcieli przeprowadzić analizę merytoryczną oferty na podstawie danych od użytkownika (z zadania **Set offer factors**) oraz pobranych automatycznie (z zadania **Get available hours**). 
- 
-Proszę zamienić zadanie **Show result** na service task (po najechaniu na element z menu kontekstowego **change element type** należy wybrać **change to service task**) i zmienić nazwę na **Evaluate offer**. Do tego zadania podepniemy klasę w Javie, która przetworzy dane z procesu. 
- 
-Specyfikacja logiki zadania w Javie możliwa jest poprzez wybranie odpowiedniej klasy w polu ''​activiti:​class''​ w zadaniu typu //Service task//. Klasa taka musi implementować interfejs ''​JavaDelegate''​ i nadpisywać funkcję ''​public void execute(DelegateExecution execution)'',​ która jest wywoływana w momencie uruchamiania tasku. 
- 
-Proszę stworzyć klasę Evaluation.java:​ 
- 
-<code java Evaluation.java>​ 
- 
-package pl.org.bpmn;​ 
-import org.activiti.engine.delegate.DelegateExecution;​ 
-import org.activiti.engine.delegate.JavaDelegate;​ 
- 
-public class Evaluation implements JavaDelegate { 
- @Override 
- public void execute(DelegateExecution execution) { 
- //TODO 
- } 
-} 
-</​code>​ 
- 
-W klasie tej przy pomocy metody ''​execution.getVariable()''​ proszę odczytać wartości potencjalnych czynników analizy merytorycznej (pobranych wcześniej od użytkownika oraz możliwości produkcyjnych zespołu -- dostępnych osobogodzin),​ a następnie zaimplementować poniżej opisaną logikę, która zwróci (przy pomocy ''​execution.setVariable()''​) odpowiedni wynik analizy merytorycznej. 
- 
-Załóżmy, że wynik analizy merytorycznej jest negatywny, w każdym z następujących przypadków: ​ 
-  * Niewystarczające kompetencje zespołu. 
-  * Przewidywane,​ wymagane zasoby przekraczają możliwości produkcyjne zespołu o 50%. 
-  * Przewidywane,​ wymagane zasoby przekraczają możliwości produkcyjne zespołu i oferta jest mało atrakcyjna. 
- 
-Po zaimplementowaniu odpowiedniej logiki pozostaje dodać klasę do odpowiedniego zadania, które ma ona obsługiwać:​ 
- 
-{{  :​pl:​dydaktyka:​bim:​lab4:​eclipse3-task-eval.png ​ |}} 
- 
-Na koniec należałoby wyświetlić wynik analizy w zadaniu **Show checking result**, \\ np. przy użyciu odpowiedniego komunikatu w  polu ''​description''​. 
- 
-Proszę uruchomić test i sprawdzić zachowanie stworzonego procesu powiązanego z klasą w Javie. 
- 
-DO SPRAWOZDANIA:​ 
-  * Proszę w sprawozdaniu umieścić model, rozbudowany test. 
-  * Proszę umieścić screenshot z eclipsa z rezultatem testu. 
- 
-==== Obsługa błędów/​wyjątków ==== 
-{{  :​pl:​dydaktyka:​bim:​lab4:​eclipse3-error-throwing.png|}} 
-W przypadku, gdy wynik analizy merytorycznej jest negatywny, proces powinien zostać przerwany, gdyż dalsze przetwarzanie oferty jest zbyteczne. W takim wypadku można użyć zdarzenia końcowego, które sygnalizuje błąd, a następnie przechwycić ten błąd innym zdarzeniem np. na krawędzi podprocesu. \\  
-Aby zdarzenia te się poprawnie komunikowały istone jest, by nadać im jednakowy ''​errorCode''​ w konfiguracji.\\ ​ 
-W ten sposób możemy przerwać wykonywanie podprocesu, po czym zakończyć cały proces (tak jak na rysunku obok). 
-Proszę dodać do modelu obsługę błędu, po czym przetestować jego działanie. ​ 
- 
-==== Uzupełnienie procesu o elementy konieczne do uruchomienia w Activiti Explorerze ==== 
- 
-Na kolejnych zajęciach przygotujemy paczkę do wdrożenia tak rozbudowanego projektu w Activiti Explorerze. 
-Jeśli jednak chcemy uruchomić proces w Activiti Explorerze musimy jeszcze uzupełnić zadania typu //User task// o użytkownika ''​assignee'',​ tak byśmy mogli zatwierdzać odpowiednie zadania. ​ 
  
pl/dydaktyka/bim/lab4.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0