Мост событий CDI

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

Процессный движок можно подключить к шине событий CDI. Мы называем это "мостом событий CDI" (CDI Event Bridge). Это позволяет получать уведомления о событиях процесса с помощью стандартных механизмов событий CDI. Чтобы включить поддержку CDI-событий для встроенного процессного движка, активируйте соответствующий parse listener в конфигурации:

<property name="postParseListeners">
  <list>
    <bean class="io.openbpm.bpm.engine.cdi.impl.event.CdiEventSupportBpmnParseListener" />
  </list>
</property>

Теперь движок настроен на публикацию событий через шину событий CDI.

Приведённую выше конфигурацию можно использовать вместе со встроенным процессным движком. Если вы хотите использовать эту возможность совместно с разделяемым процессным движком в среде с несколькими приложениями, необходимо добавить CdiEventListener как слушатель событий процессного приложения. См. следующий раздел.

Ниже приведён обзор того, как можно получать события процесса в CDI-бинах. В CDI можно декларативно задавать наблюдателей событий с помощью аннотации @Observes. Уведомления о событиях типобезопасны. Тип событий процесса: io.openbpm.bpm.engine.cdi.BusinessProcessEvent. Ниже показан пример простого метода-наблюдателя:

public void onProcessEvent(@Observes BusinessProcessEvent businessProcessEvent) {
// handle event
}

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

  • @BusinessProcessDefinition: ограничивает набор событий определённым определением процесса. Пример:

      public void onProcessEvent(@Observes @BusinessProcessDefinition("billingProcess") BusinessProcessEvent businessProcessEvent) {
      // handle event
      }
  • @StartActivity: ограничивает набор событий определённой активностью. Например:

      public void onActivityEvent(@Observes @StartActivity("shipGoods") BusinessProcessEvent businessProcessEvent) {
      // handle event
      }

    Метод вызывается каждый раз, когда выполняется вход в активность с идентификатором shipGoods.

  • @EndActivity: ограничивает набор событий определённой активностью. Следующий метод вызывается каждый раз, когда происходит выход из активности с идентификатором shipGoods:

      public void onActivityEvent(@Observes @EndActivity("shipGoods") BusinessProcessEvent businessProcessEvent) {
      // handle event
      }
  • @TakeTransition: ограничивает набор событий определённым переходом.

  • @CreateTask: ограничивает набор событий определённой задачей. Следующий метод вызывается каждый раз, когда создаётся задача с definition key (id в BPMN XML) approveRegistration:

    public void onTaskEvent(@Observes @CreateTask("approveRegistration") BusinessProcessEvent businessProcessEvent) {
    // handle event
    }
  • @AssignTask: ограничивает набор событий определённой задачей. Следующий метод вызывается каждый раз, когда назначается задача с definition key (id в BPMN XML) approveRegistration:

    public void onTaskEvent(@Observes @AssignTask("approveRegistration") BusinessProcessEvent businessProcessEvent) {
    // handle event
    }
  • @CompleteTask: ограничивает набор событий определённой задачей. Следующий метод вызывается каждый раз, когда завершается задача с definition key (id в BPMN XML) approveRegistration:

    public void onTaskEvent(@Observes @CompleteTask("approveRegistration") BusinessProcessEvent businessProcessEvent) {
    // handle event
    }
  • @DeleteTask: ограничивает набор событий определённой задачей. Следующий метод вызывается каждый раз, когда удаляется задача с definition key (id в BPMN XML) approveRegistration:

      public void onTaskEvent(@Observes @DeleteTask("approveRegistration") BusinessProcessEvent businessProcessEvent) {
      // handle event
      }

Указанные выше квалификаторы можно свободно комбинировать. Например, чтобы получать все события, генерируемые при выходе из активности shipGoods в процессе shipmentProcess, можно объявить следующий метод-наблюдатель:

public void beforeShippingGoods(@Observes @BusinessProcessDefinition("shippingProcess") @EndActivity("shipGoods") BusinessProcessEvent evt) {
  // handle event
}

В конфигурации по умолчанию слушатели событий вызываются синхронно и в контексте одной и той же транзакции. Транзакционные CDI-наблюдатели (доступны только в сочетании с Jakarta EE / Java EE / EJB) позволяют управлять моментом, когда событие передаётся в метод-наблюдатель. Используя транзакционных наблюдателей, можно, например, гарантировать, что наблюдатель получит уведомление только в том случае, если транзакция, в которой было сгенерировано событие, завершится успешно:

public void onShipmentSuceeded(
  @Observes(during=TransactionPhase.AFTER_SUCCESS) @BusinessProcessDefinition("shippingProcess") @EndActivity("shipGoods") BusinessProcessEvent evt) {

  // send email to customer
}

Примечание: BusinessProcessEvent.getTask вернёт экземпляр DelegateTask (если событие относится к задаче). Если слушатель вызывается после завершения транзакции, объект DelegateTask нельзя использовать для изменения переменных.

Мост событий CDI в процессном приложении

Чтобы использовать CDI Event Bridge в комбинации с multi-application deployment и разделяемым процессным движком, необходимо добавить io.openbpm.bpm.engine.cdi.impl.event.CdiEventListener как слушатель событий выполнения процессного приложения.

Пример конфигурации для Servlet-процессного приложения:

@ProcessApplication
public class InvoiceProcessApplication extends ServletProcessApplication {

  protected CdiEventListener cdiEventListener = new CdiEventListener();

  public ExecutionListener getExecutionListener() {
    return cdiEventListener;
  }

  public TaskListener getTaskListener() {
    return cdiEventListener;
  }
}

Пример конфигурации для EJB-процессного приложения:

@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@ProcessApplication
@Local(ProcessApplicationInterface.class)
public class MyEjbProcessApplication extends EjbProcessApplication {

  protected CdiEventListener cdiEventListener = new CdiEventListener();

  @PostConstruct
  public void start() {
    deploy();
  }

  @PreDestroy
  public void stop() {
    undeploy();
  }

  public ExecutionListener getExecutionListener() {
    return cdiEventListener;
  }

  public TaskListener getTaskListener() {
    return cdiEventListener;
  }
}

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

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

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