UniBPM External Task
Обзор
UniBPM External Task Starter расширяет механизм External Task и добавляет:
- Автоматическое извлечение
extensionPropertiesиз BPMN - Маршрутизацию по
connector / action / version - Диспетчеризацию задач через Kafka
- Обработку результатов через Kafka
- Плагинную архитектуру коннекторов
- Spring Boot starter с автоконфигурацией
Это позволяет строить слабосвязанные интеграционные сервисы без прямого REST-polling к Process Engine.
Архитектура
Process Engine
│
│ (создание External Task)
▼
ExternalTaskCreateHandler (Engine)
│
│ 1. Читает extension properties
│ 2. Определяет connector/action/version
│ 3. Публикует Job в Kafka
▼
Kafka Topic (jobs.{topic}.{env})
│
▼
unibpm-integration-runtime
│
│ Обрабатывает задачу
│ Публикует результат
▼
Kafka Topic (results)
│
▼
ExternalTaskResponseHandler (Engine)
│
▼
Process Engine
(complete / bpmnError / failure)
Настройка BPMN
Service Task должен быть объявлен как external и содержать extension properties:
<bpmn:serviceTask id="Activity_1h87cc2"
name="Log Info"
camunda:type="external"
camunda:topic="finance">
<bpmn:extensionElements>
<camunda:properties>
<camunda:property name="uni.connector" value="demo"/>
<camunda:property name="uni.action" value="log.info"/>
<camunda:property name="uni.version" value="v1"/>
</camunda:properties>
</bpmn:extensionElements>
</bpmn:serviceTask>
Обязательные свойства
| Свойство | Назначение |
|---|---|
uni.connector | Логическая группа интеграции |
uni.action | Бизнес-действие |
uni.version | Версия обработчика |
Комбинация этих трёх параметров уникально определяет обработчик.
Разрешение обработчиков
Обработчик определяется по триаде:
connector + action + version
Пример:
demo / log.info / v1
Если обработчик не найден, будет выброшено исключение:
IllegalStateException:
No handler found for connector/action/version: demo/log.info/v1
Это fail-fast поведение.
Реализация коннектора
Для создания интеграционного обработчика необходимо реализовать интерфейс:
ExternalTaskHandler {}
Пример:
@Component
public class DemoLogInfoV1Handler implements ExternalTaskHandler {
@Override
public String getConnector() {
return "demo";
}
@Override
public String getAction() {
return "log.info";
}
@Override
public String getVersion() {
return "v1";
}
@Override
public ExternalTaskResult handle(ExternalTaskJob job) {
log.info("DEMO handler invoked. taskId={}, businessKey={}",
job.getTaskId(),
job.getBusinessKey());
return ExternalTaskResult.completed()
.addVariable("demoHandled", true);
}
}
Обработчик должен быть Spring Bean.
Kafka Topics
Топик задач (Jobs)
Формат:
{organization}.unibpm.external-task.jobs.{camundaTopic}.{environment}
Пример:
reunico.unibpm.external-task.jobs.finance.prod
Топик результатов (Results)
{organization}.unibpm.external-task.results.{environment}
Пример:
reunico.unibpm.external-task.results.prod
Контракт Job
Пример сообщения задачи:
{
"taskId": "be016126-11b5-11f1-ae9a-2677461d85a5",
"processInstanceId": "8e812bf3-2101-4dfe-8b3c-617277b6e43a",
"businessKey": "8e812bf3-2101-4dfe-8b3c-617277b6e43a",
"connector": "demo",
"action": "log.info",
"version": "v1",
"variables": {
"amount": 1000
}
}
Контракт Result
Успешное завершение
{
"taskId": "...",
"status": "COMPLETED",
"variables": {
"result": "OK"
}
}
BPMN Error
{
"taskId": "...",
"status": "BPMN_ERROR",
"errorCode": "BUSINESS_ERROR",
"errorMessage": "Validation failed"
}
Failure (техническая ошибка)
{
"taskId": "...",
"status": "FAILED",
"failureMessage": "System error",
"retries": 3,
"retryDuration": 60000
}
Извлечение Extension Properties
UniBPM извлекает extension properties через метод:
externalTask.getExtensionProperties()
возвращает пустой Map.
Spring Boot Starter
Интеграционный клиент подключается через starter:
unibpm-external-task-client-starter
Он автоматически:
- Регистрирует Kafka consumer
- Создаёт registry обработчиков
- Подключает dispatcher
- Настраивает JSON сериализацию
- Поддерживает conditional автоконфигурацию
Обработка ошибок
| Сценарий | Поведение |
|---|---|
| Нет обработчика | IllegalStateException |
| Обработчик выбросил RuntimeException | Отправляется FAILED |
| Обработчик выбросил BpmnErrorException | Отправляется BPMN_ERROR |
| Сообщение не десериализуется | Ошибка consumer (рекомендуется ErrorHandlingDeserializer) |
| Повторная доставка | Обработчик должен быть идемпотентным |
Принципы проектирования
- BPMN определяет контракт интеграции
- Kafka обеспечивает асинхронную развязку
- Обработчики stateless
- Версионирование обеспечивает обратную совместимость
- Engine не зависит от конкретных интеграций
- Интеграции масштабируются независимо
Итог
UniBPM External Task Integration обеспечивает:
- Чёткий контракт
- Масштабируемость
- Расширяемость
- Изоляцию бизнес-контекста
- Production-ready архитектуру