跳到主要内容

Flowable Event Registry API

Doubao 中英对照 The Flowable Event Registry API

Event Registry 引擎 API 与服务​

Event Registry 引擎 API 是与 Flowable Event Registry 交互最常用的方式。核心起点是 EventRegistryEngine,可如配置章节所述以多种方式创建。从 EventRegistryEngine 可以获取各种其他服务。EventRegistryEngine 和服务对象都是线程安全的。因此你可以在整个服务器生命周期内持有其中某个对象的引用。

EventRegistryEngine eventRegistryEngine = EventRegistryEngines.getDefaultEventRegistryEngine();
EventRegistry eventRegistry = eventRegistryEngine.getEventRegistry();
EventRepositoryService eventRepositoryService = eventRegistryEngine.getEventRepositoryService();
EventManagementService eventManagementService = eventRegistryEngine.getEventManagementService();

EventRegistryEngines.getDefaultEventRegistryEngine() 在第一次调用时初始化并构建 Event Registry 引擎,之后始终返回同一个 Event Registry 引擎。所有 Event Registry 引擎的正确创建与关闭可通过 EventRegistryEngines.init() 和 EventRegistryEngines.destroy() 完成。

EventRegistryEngines 类会扫描所有 flowable.eventregistry.cfg.xml 和 flowable-eventregistry-context.xml 文件。对于所有 flowable.eventregistry.cfg.xml 文件,Event Registry 引擎将以典型的 Flowable 方式构建:EventRegistryEngineConfiguration.createEventRegistryEngineConfigurationFromInputStream(inputStream).buildEventRegistryEngine()。对于所有 flowable-eventregistry-context.xml 文件,Event Registry 引擎将以 Spring 方式构建:首先创建 Spring 应用上下文,然后从该应用上下文获取 Event Registry 引擎。

所有服务都是无状态的。这意味着你可以轻松地在集群中的多个节点上运行 Flowable Event Registry,每个节点都连接到同一个数据库,而无需担心哪台机器实际执行了之前的调用。对任何服务的任何调用都是幂等的,无论它在何处执行。

EventRepositoryService 大概是使用 Flowable Event Registry 引擎时第一个需要的服务。该服务提供用于管理和操作部署以及 Event 和 Channel 定义的操作。
事件定义用于配置事件载荷和关联参数,并定义与特定通道定义 key 的关系。
通道定义配置传入或传出事件的源或目标目的地。例如,通道定义可以为名为 orderQueue 的 JMS 队列定义一个 JMS 监听器。
部署是 Flowable Event Registry 引擎内的打包单元。一个部署可以包含多个 Event 和 Channel 定义 JSON 文件。部署一个部署意味着将其上传到引擎,在那里所有 Event 和 Channel 定义都会被检查和解析,然后存储到数据库。从那时起,该部署即为系统所知,部署中包含的任何事件和通道定义现在都可以使用。

此外,该服务还允许你:

  • 查询引擎已知的部署、Event 和 Channel 定义。
  • 获取 Event 和 Channel 定义的 POJO 版本,可使用 Java 而非 JSON 进行内省。

EventRegistry 提供接收和发送事件实例的方法。它还提供添加和移除事件消费者的方法。

使用 Flowable Event Registry 编写自定义应用时,通常不需要 EventManagementService。它允许你检索有关引擎版本、数据库表和表元数据的信息。

有关服务操作和 Event Registry 引擎 API 的更详细信息,参见 javadocs。

异常策略​

Flowable 中的基异常是 org.flowable.engine.FlowableException,这是一个非受检异常。该异常随时可能由 API 抛出,但特定方法中发生的“预期”异常已在 javadocs 中记录。

/**
* Retrieves the Java representation of an event definition.
*
* @param eventDefinitionKey the event definition key, cannot be null
* @return the event model Java representation.
*/
EventModel getEventModelByKey(String eventDefinitionKey);

在上面的示例中,当传入一个不存在事件定义的 key 时,将抛出异常。此外,由于 javadoc 明确说明 eventDefinitionKey 不能为 null,传入 null 时将抛出 FlowableIllegalArgumentException。

尽管我们希望避免庞大的异常层次结构,但在特定情况下会抛出以下子类。执行或 API 调用期间发生的、不属于下列可能异常的所有其他错误,都作为常规 FlowableException 抛出。

  • FlowableOptimisticLockingException:当数据存储中因同一数据条目被并发访问而发生乐观锁时抛出。
  • FlowableClassLoadingException:当请求加载的类未找到或加载时发生错误时抛出。
  • FlowableObjectNotFoundException:当请求或操作的对象不存在时抛出。
  • FlowableIllegalArgumentException:表示在 Flowable Event Registry API 调用中提供了非法参数、引擎配置中配置了非法值,或提供了非法值的异常。

Query API​

Query API 允许用流式 API 编写完全类型安全的查询。你可以向查询添加各种条件(所有条件以逻辑 AND 一起应用)以及恰好一种排序方式。下面的代码展示了一个示例:

List<EventDeployment> eventDeployments = eventRepositoryService.createDeploymentQuery()
.deploymentNameLike("deployment%")
.orderByDeployTime()
.list();

单元测试​

由于 Flowable Event Registry 是一个可嵌入的 Java 引擎,为 Event 和 Channel 定义编写单元测试就像编写常规单元测试一样简单。

Flowable 支持 JUnit Jupiter 风格的单元测试。

在 JUnit Jupiter 风格中,需要注册 org.flowable.eventregistry.test.FlowableEventExtension。注册 FlowableEventExtension 可以用 @ExtendWith(FlowableEventExtension.class) 完成。这将使 EventRegistryEngine 和服务作为参数可用于测试和生命周期方法(@BeforeAll、@BeforeEach、@AfterEach、@AfterAll)。每个测试之前,默认会用 classpath 上的 flowable.eventregistry.cfg.xml 资源初始化 eventRegistryEngine。为了指定不同的配置文件,需要使用 org.flowable.eventregistry.test.EventConfigurationResource 注解(见第二个示例)。当配置资源相同时,Event Registry 引擎会在多个单元测试之间静态缓存。

通过使用 EventRegistryEngine,你可以用 org.flowable.eventregistry.test.EventDeploymentAnnotation 注解测试方法。当测试方法用 @EventDeploymentAnnotation 注解时,每个测试之前将部署 EventDeploymentAnnotation#resources 中定义的事件定义文件。如果未定义资源,将部署与测试类同包下、形式为 testClassName.testMethod.event 的资源文件。测试结束时,将删除该部署,包括所有相关的事件和通道定义。更多信息参见 EventDeploymentAnnotation 类。

此外,通过使用 EventRegistryEngine,你可以用 org.flowable.eventregistry.test.ChannelDeploymentAnnotation 注解测试方法。当测试方法用 @ChannelDeploymentAnnotation 注解时,每个测试之前将部署 ChannelDeploymentAnnotation#resources 中定义的通道定义文件。如果未定义资源,将部署与测试类同包下、形式为 testClassName.testMethod.channel 的资源文件。测试结束时,将删除该部署,包括所有相关的事件和通道定义。更多信息参见 EventDeploymentAnnotation 类。

综合考虑以上内容,JUnit Jupiter 测试如下所示:

使用默认资源的 JUnit Jupiter 测试。

@ExtendWith(FlowableEventExtension.class)
class MyEventDefinitionTest {

@Test
@EventDeploymentAnnotation
void simpleEventDefinitionTest(EventRegistryEngine eventRegistryEngine) {
EventRepositoryService repositoryService = eventRegistryEngine.getEventRepositoryService();
EventDefinition eventDefinition = repositoryService.createEventDefinitionQuery()
.eventDefinitionKey("myEvent")
.latestVersion()
.singleResult();
assertNotNull(eventDefinition);
assertEquals("myEvent", eventDefinition.getKey());
assertEquals(1, eventDefinition.getVersion());
}
}

使用自定义资源的 JUnit Jupiter 测试。

@ExtendWith(FlowableEventExtension.class)
@EventConfigurationResource("flowable.custom.eventregistry.cfg.xml")
class MyEventDefinitionTest {

@Test
@EventDeploymentAnnotation
void simpleEventDefinitionTest(EventRegistryEngine eventRegistryEngine) {
EventRepositoryService repositoryService = eventRegistryEngine.getEventRepositoryService();
EventDefinition eventDefinition = repositoryService.createEventDefinitionQuery()
.eventDefinitionKey("myEvent")
.latestVersion()
.singleResult();
assertNotNull(eventDefinition);
assertEquals("myEvent", eventDefinition.getKey());
assertEquals(1, eventDefinition.getVersion());
}
}

Web 应用中的 Event Registry 引擎​

EventRegistryEngine 是一个线程安全的类,可以轻松地在多个线程之间共享。在 web 应用中,这意味着可以在容器启动时创建一次 Event Registry 引擎,并在容器关闭时关闭该引擎。

下面的代码片段展示了如何编写一个简单的 ServletContextListener,在纯 Servlet 环境中初始化和销毁流程引擎:

public class EventRegistryEnginesServletContextListener implements ServletContextListener {

public void contextInitialized(ServletContextEvent servletContextEvent) {
EventRegistryEngines.init();
}

public void contextDestroyed(ServletContextEvent servletContextEvent) {
EventRegistryEngines.destroy();
}

}

contextInitialized 方法将委托给 EventRegistryEngines.init()。这会在 classpath 上查找 flowable.eventregistry.cfg.xml 资源文件,并为给定的配置创建一个 EventRegistryEngine(例如,多个带有配置文件的 JAR)。如果 classpath 上有多个此类资源文件,请确保它们都有不同的名称。需要 Event Registry 引擎时,可以使用以下方式获取:

EventRegistryEngines.getDefaultEventRegistryEngine()

或:

EventRegistryEngines.getEventRegistryEngine("myName");

当然,也可以使用创建 Event Registry 引擎的任何变体,如配置章节所述。

上下文监听器的 contextDestroyed 方法委托给 EventRegistryEngines.destroy()。这将正确关闭所有已初始化的 Event Registry 引擎。