External Task Client Spring Boot Starter

Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine

OpenBPM Engine предоставляет Spring Boot Starter для External Task Client. Это позволяет легко добавить External Task Client в ваше Spring Boot-приложение, добавив следующую Maven-зависимость в файл pom.xml:

<dependency>
  <groupId>io.openbpm.bpm.springboot</groupId>
  <artifactId>openbpm-engine-bpm-spring-boot-starter-external-task-client</artifactId>
  <version>{latest-version}</version>
</dependency>

Ознакомьтесь с нашими примерами для External Task Client Spring Boot Starter.

Клиент может подписываться на одно или несколько имён топиков (topic names), определённых в вашей BPMN-модели процесса. Когда выполнение ожидает на External Task, Клиент выполняет вашу пользовательскую бизнес-логику. Например, проверяется кредитный рейтинг клиента, и в случае успеха External Task может быть отмечена как завершённая, после чего выполнение продолжается дальше.

Требования

External Task Client Spring Boot Starter требует Java 17.

Подписка на топик (Topic Subscription)

Интерфейс, который позволяет реализовать пользовательскую бизнес-логику и взаимодействовать с Engine, называется ExternalTaskHandler. Подписка идентифицируется именем топика и настраивается с ссылкой на bean ExternalTaskHandler.

Вы можете подписать Клиент на топик creditScoreChecker, определив bean с возвращаемым типом ExternalTaskHandler и аннотировав этот bean следующим образом:

@ExternalTaskSubscription("creditScoreChecker")

Аннотация требует как минимум имя топика. Однако вы можете применить дополнительные параметры конфигурации, либо сославшись на имя топика в файле application.yml:

openbpm.bpm.client:
  base-url: http://localhost:8080/engine-rest
  subscriptions:
    creditScoreChecker:
        process-definition-key: loan_process
        include-extension-properties: true
        variable-names: defaultScore

Или задав атрибуты конфигурации прямо в аннотации:

@ExternalTaskSubscription(
  topicName = "creditScoreChecker",
  processDefinitionKey = "loan_process",
  includeExtensionProperties = true,
  variableNames = "defaultScore"
)

Обратите внимание: свойство, заданное в файле application.yml, всегда переопределяет соответствующий атрибут, заданный программно через аннотацию.

Пример конфигурации обработчика (Handler)

Рассмотрите следующий полный пример bean-обработчика:

@Configuration
@ExternalTaskSubscription("creditScoreChecker")
public class CreditScoreCheckerHandler implements ExternalTaskHandler {

  @Override
  public void execute(ExternalTask externalTask,
                      ExternalTaskService externalTaskService) {
    // add your business logic here
  }

}

Если вы хотите определить несколько bean-обработчиков в рамках одного класса конфигурации, это можно сделать так:

@Configuration
public class HandlerConfiguration {

  @Bean
  @ExternalTaskSubscription("creditScoreChecker")
  public ExternalTaskHandler creditScoreCheckerHandler() {
    return (externalTask, externalTaskService) -> {
      // add your business logic here
      externalTaskService.complete(externalTask);
    };
  }

  @Bean
  @ExternalTaskSubscription("loanGranter")
  public ExternalTaskHandler loanGranterHandler() {
    return (externalTask, externalTaskService) -> {
      // add your business logic here
      externalTaskService.complete(externalTask);
    };
  }

}

Открытие/закрытие подписки на топик (Topic Subscription)

Если не выполнена дополнительная настройка, подписка на топик автоматически открывается при запуске Spring Boot приложения — то есть Клиент немедленно начинает выбирать (fetch) External Tasks, относящиеся к имени топика.

В некоторых ситуациях подписку на топик не следует открывать сразу при запуске приложения. Этим можно управлять с помощью флага auto-open /#auto-open.

Интерфейс SpringTopicSubscription позволяет открывать или закрывать топик программно сразу после того, как подписка была инициализирована. Процесс инициализации запускается сразу после старта приложения.

Когда подписка инициализирована, публикуется событие SubscriptionInitializedEvent, и подписку на топик можно открыть или закрыть:

@Configuration
public class SubscriptionInitializedListener
    implements ApplicationListener<SubscriptionInitializedEvent> {

  @Override
  public void onApplicationEvent(SubscriptionInitializedEvent event) {

    SpringTopicSubscription topicSubscription = event.getSource();

    String topicName = topicSubscription.getTopicName();
    boolean isOpen = topicSubscription.isOpen();
    if ("creditScoreChecker".equals(topicName)) {

      if(!isOpen) {
        // Start fetching for External Tasks
        topicSubscription.open();

      } else {
        // Stop fetching for External Tasks
        topicSubscription.close();

      }
    }
  }

}

Конфигурация

Файл application.yml

Центральная точка конфигурации — файл application.yml.

Инициализация клиента (Client Bootstrapping)

Убедитесь, что свойства настраиваются с префиксом: openbpm.bpm.client

Пример конфигурации может выглядеть следующим образом:

openbpm.bpm.client:
  base-url: http://localhost:8080/engine-rest
  worker-id: spring-boot-worker
  basic-auth:
    username: admin
    password: admin

Доступные свойства:

Property name Description Default value

base-url

Обязательно: базовый URL Camunda 7 RuntimeREST API.

worker-id

Пользовательский идентификатор worker, известный Workflow Engine.
Примечание: убедитесь, что выбран уникальный worker id.

hostname + 128 bit UUID

max-tasks

Задаёт максимальное количество задач, которое может быть выбрано в рамках одного запроса.

10

use-priority

Определяет, следует ли выбирать задачи на основе их приоритета или произвольно.

true

use-create-time

Определяет, следует ли выбирать задачи на основе времени их создания (create time) в порядке убывания. Используйте это свойство совместно со свойством order-by-create-time, иначе будет выброшено исключение SpringExternalTaskClientException.

false

order-by-create-time

Определяет, следует ли выбирать задачи на основе их createTime с указанным порядком сортировки. Может быть "asc" или "desc". Используйте это свойство совместно со свойством use-create-time, иначе будет выброшено исключение SpringExternalTaskClientException.

null

async-response-timeout

Асинхронный ответ (long polling) включается, если задан таймаут. Задаёт максимальное время ожидания ответа для выбранных (fetched) и заблокированных (locked) External Tasks. Ответ возвращается немедленно, если External Tasks доступны в момент запроса.

null

disable-auto-fetching

Отключает немедленную выборку (fetching) внешних задач после инициализации Клиента. Чтобы начать выборку, необходимо вызвать ExternalTaskClient#start().

false

disable-backoff-strategy

Отключает стратегию backoff на стороне клиента. Если установлено в true, bean BackoffStrategy игнорируется.

Heads-up: имейте в виду, что отключение client-side backoff может привести к тяжёлым нагрузочным ситуациям на стороне engine. Чтобы избежать этого, задайте подходящий async-response-timeout.

false

lock-duration

Задаёт, на сколько миллисекунд блокируется External Task. Должно быть больше нуля. Переопределяется длительностью блокировки, настроенной на подписке топика.

20,000

date-format

Задаёт формат даты для де-/сериализации переменных даты.

yyyy-MM-dd’T’HH:mm:ss.SSSZ

default-serialization-format

Задаёт формат сериализации, используемый для сериализации объектов, когда не запрошен конкретный формат.

application/json

basic-auth.username

Задаёт имя пользователя для аутентификации в REST API.

basic-auth.password

Задаёт пароль для аутентификации в REST API.

Подписка на топик (Topic Subscription)

Свойства подписок на топики задаются в: openbpm.bpm.client.subscriptions

Свойства конфигурации можно применить для каждого имени топика следующим образом:

openbpm.bpm.client:
  # ADD CLIENT CONFIGURATION HERE
  subscriptions:
    creditScoreChecker:
        process-definition-key: loan_process
        include-extension-properties: true
        variable-names: defaultScore
    loanGranter:
        process-definition-key: loan_process

Доступные свойства:

Property name Description Default value

${TOPIC_NAME}

Имя топика Service Task в BPMN-модели процесса, на который Клиент подписывается.

auto-open

Если false, подписку на топик можно открыть после старта приложения, вызвав SpringTopicSubscription#open(). В противном случае Клиент немедленно начинает выбирать (fetch) External Tasks.

true

lock-duration

Задаёт, на сколько миллисекунд блокируется External Task. Должно быть больше нуля. Переопределяет длительность блокировки, настроенную при инициализации Клиента.

20,000

variable-names

Имена переменных, которые необходимо получить. По умолчанию получаются все переменные.

null

local-variables

Определяет, нужно ли выбирать переменные из области видимости больше, чем у External Task. Если false, будут выбраны все переменные, видимые в области видимости. Если true, будут выбраны только локальные переменные для области видимости External Task.

false

include-extension-properties

Определяет, включать ли пользовательские extension properties для выбранных External Tasks. Если true, все extensionProperties, определённые в External Service Task, будут предоставлены. Если false, extensionProperties, определённые в External Service Task, будут проигнорированы.

false

business-key

Выбираются только External Tasks, связанные с указанным business key.

process-definition-id

Выбираются только External Tasks, связанные с указанным process definition id.

process-definition-id-in

Выбираются только External Tasks, связанные с указанным списком process definition ids. Список ids имеет семантику логического OR.

process-definition-key

Выбираются только External Tasks, связанные с указанным process definition key.

process-definition-key-in

Выбираются только External Tasks, связанные с указанным списком process definition keys. Список keys имеет семантику логического OR.

process-definition-version-tag

Выбираются только External Tasks, связанные с указанным version tag определения процесса.

process-variables

Выбираются только External Tasks, связанные с указанной map процессных переменных (key: имя переменной, value: значение переменной). Map переменных имеет семантику логического OR.

without-tenant-id

Выбираются только External Tasks без tenant id.

tenant-id-in

Выбираются только External Tasks, связанные с указанным списком tenant ids. Список ids имеет семантику логического OR.

Логирование (Logging)

Чтобы логировать внутреннюю работу Клиента, установите уровень логгера io.openbpm.bpm.client.spring в DEBUG.

Вы можете задать уровень логирования в файле application.yml следующим образом:

logging.level.io.openbpm.bpm.client.spring: DEBUG

Для отладки также может быть полезно повысить уровень логгера io.openbpm.bpm.client.

Перехватчик запросов (Request Interceptor)

Перехватчик запросов вызывается каждый раз, когда Клиент выполняет HTTP-запрос. Вы можете использовать эту точку расширения, например, чтобы реализовать пользовательскую стратегию аутентификации, такую как OAuth 2.0.

Вы можете зарегистрировать один или несколько перехватчиков запросов, определив beans типа ClientRequestInterceptor:

@Configuration
public class RequestInterceptorConfiguration implements ClientRequestInterceptor {
  // ...
}

Стратегия backoff (Backoff Strategy)

По умолчанию Клиент использует экспоненциальную стратегию backoff. Вы можете заменить её пользовательской стратегией, определив bean типа BackoffStrategy:

@Configuration
public class BackoffStrategyConfiguration implements BackoffStrategy {
  // ...
}

Разрешение свойств (Resolving Properties)

Строковые свойства конфигурации Клиента могут разрешаться из пользовательского файла свойств путём определения bean типа PropertySourcesPlaceholderConfigurer:

@Configuration
public class PropertyPlaceholderConfiguration
    extends PropertySourcesPlaceholderConfigurer {

  public PropertyPlaceholderConfiguration() {
    // Specify the *.properties file name that contains the property placeholders
    Resource location = new ClassPathResource("client.properties");
    setLocation(location);
  }

}

При использовании приведённого выше примера Клиент пытается разрешить строковые свойства из файла client.properties следующим образом:

client.baseUrl=http://localhost:8080/engine-rest
client.workerId=spring-boot-worker
client.dateFormat=yyyy-MM-dd'T'HH:mm:ss.SSSZ
client.serializationFormat=application/json

Убедитесь, что вы ссылаетесь на соответствующие placeholders, определённые выше, в вашем файле application.yml:

openbpm.bpm.client:
  base-url: ${client.baseUrl}
  worker-id: ${client.workerId}
  date-format: ${client.dateFormat}
  default-serialization-format: ${client.serializationFormat}

Пользовательский клиент (Custom Client)

Вы можете инициализировать Клиент программно, тем самым пропуская внутреннее создание Клиента:

@Configuration
public class CustomClientConfiguration {

  @Bean
  public ExternalTaskClient customClient() {
    return ExternalTaskClient.create()
        .baseUrl("http://localhost:8080/engine-rest")
        .build();
  }

}

Beans

Вы можете определять beans обработчиков, но также некоторые beans определяются внутри, и вы не можете ими управлять. Однако к этим beans можно получить доступ через autowiring.

Bean клиента (Client Bean)

Если пользователь не определил его заранее (см. Custom Client #_custom_client), создаётся bean с именем externalTaskClient типа ExternalTaskClient.

Bean подписки (Subscription Bean)

На основе bean-обработчика, аннотированного @ExternalTaskSubscription, создаётся bean подписки типа SpringTopicSubscription. Имя bean формируется как:

handler bean name + "Subscription"

Например, следующая декларация bean-обработчика:

@Bean
@ExternalTaskSubscription("creditScoreChecker")
public ExternalTaskHandler creditScoreCheckerHandler() {
  // ...
}

Приведёт к имени bean подписки:

creditScoreCheckerHandlerSubscription

Модуль только для Spring (Spring-only Module)

Если вы хотите использовать Spring вместо Spring Boot, вы можете добавить следующую Maven-зависимость в файл pom.xml:

<dependency>
  <groupId>io.openbpm.bpm</groupId>
  <artifactId>openbpm-engine-external-task-client-spring</artifactId>
  <version>{latest-version}</version>
</dependency>

Чтобы инициализировать Клиент, используйте аннотацию класса @EnableExternalTaskClient.

Лицензия и атрибуция

Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .

Оригинал документации: https://docs.camunda.org