Коллеги, всем привет!
Некоторое время назад поднималась тема тестирования Timer Boundary Event, в ходе обсуждения которой была выявлена проблема, связанная с невозможностью получить значение джоба-таймера по его id из описания процесса.
Это не является большой проблемой, если таймер представлен как Intermediate Timer Event.
Вы просто бежите по процессу и встретив очередной джоб, проверяете его значение. Но как быть, если например, у меня есть user task, имеющий более двух Timer Boundary Event (как на приаттаченной модели процесса)?
timerMadness.bpmn (8.9 КБ)
Ранее такие таймеры мы тестировали несколько извращенным способом:
- Мы знаем какие значения таймеров должны быть на текущем таске
- Проверяем все таймеры таска на наличие ожидаемых значений
Но опять же, если проблема возвращается, если у нас есть два таймера с ОДИНАКОВЫМИ значениями.
Сегодня я погрузился поглубже в эту проблему и обнаружил, что интерфейс Job имеет реализацию TimerEntity. А этот TimerEntity имеет атрибут jobHandlerConfiguration, значение которого совпадает с event id из описания процесса.
Таким образом, применяя код, приведенный ниже, становится возможным получить значение таймера по его id из описания процесса. Я не уверен, что этот подход корректен. Попробую провалидировать его с коллегами из Camunda.
@Test
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_NONE)
public void shouldExecuteHappyPath() {
// given
String processDefinitionKey = "timerMadness";
Date remindDate = dateTime().plusDays(1).toDate();
Date informDate = dateTime().plusDays(5).toDate();;
Date escalationDate = dateTime().plusDays(10).toDate();;
// when
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
processDefinitionKey, withVariables(
"remindDate", remindDate,
"informDate", informDate,
"escalationDate", escalationDate
));
// then
assertThat(processInstance).isStarted().hasProcessDefinitionKey(processDefinitionKey);
assertThat(processInstance).isWaitingAt("unhappySalesGuy");
/*
assert that all jobs created with expected values
not possible to get and check timer/job values by timer definition ids (remindDate, informDate, escalationDate)
so only the way to assert timer values is get all timers and filter it by expected values
and there can be an issue if i have timers with the same values
* */
List<Job> timers = managementService
.createJobQuery()
.processInstanceId(processInstance.getId())
.timers().list();
for (Job timer : timers) {
System.out.println(((TimerEntity) timer).getJobHandlerConfigurationRaw());
}
TimerEntity escalationTimer =
timers.stream()
.map(job -> (TimerEntity) job)
.filter(timer -> timer.getJobHandlerConfigurationRaw()
.equals("escalationTimer")).findFirst().orElseThrow();
System.out.println("Actual:" + escalationTimer.getDuedate());
System.out.println("Expected:" + escalationDate);
assertEquals(escalationDate, escalationTimer.getDuedate());
// complete(task());
}