Camunda 调用方法与示例

Camunda平台提供公共API访问方式,Camunda平台公共API僅限於以下項目:

Java API

Java Api 可以访问下面几个模块

  1. camunda-engine
  2. camunda-engine-spring
  3. camunda-engine-cdi
  4. camunda-engine-dmn
  5. camunda-bpmn-model
  6. camunda-cmmn-model
  7. camunda-dmn-model
  8. camunda-spin-core
  9. camunda-connect-core
  10. camunda-commons-typed-values

HTTP API (REST API)

REST API 可以直接引用openapi的接口jar使用,对应的api规范参考定义。 在Pom中的引用方式如下:

<dependency>
    <groupId>org.camunda.bpm</groupId>
    <artifactId>camunda-engine-rest-openapi</artifactId>
    <version>7.19.0</version>
</dependency>

在Gradle中引用的方法如下:

compile group: 'org.camunda.bpm:camunda-engine-rest-openapi:7.19.0

基本API访问示例

这是图片

    #获取引擎
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    #获取存儲服務
    RepositoryService repositoryService = processEngine.getRepositoryService();
    #获取运行时服务
    RuntimeService runtimeService = processEngine.getRuntimeService();
    #获取任务服务
    TaskService taskService = processEngine.getTaskService();
    #获取身份服务
    IdentityService identityService = processEngine.getIdentityService();
    #获取表单服务
    FormService formService = processEngine.getFormService();
    #获取历史服务
    HistoryService historyService = processEngine.getHistoryService();
    #获取管理服务
    ManagementService managementService = processEngine.getManagementService();
    #获取过滤服务
    FilterService filterService = processEngine.getFilterService();
    #获取外部任务服务
    ExternalTaskService externalTaskService = processEngine.getExternalTaskService();
    #获取案例服务
    CaseService caseService = processEngine.getCaseService();
    #获取决策服务
    DecisionService decisionService = processEngine.getDecisionService();

ProcessEngines.getDefaultProcessEngine() 将在第一次调用时初始化并构建流程引擎,之后始终返回相同的流程引擎。 可以使用 ProcessEngines.init() 和 ProcessEngines.destroy() 正确创建和关闭所有流程引擎。

ProcessEngines 类将扫描所有 camunda.cfg.xml 和 activiti.cfg.xml 文件。 对于所有 camunda.cfg.xml 文件,流程引擎将以典型方式构建:

    ProcessEngineConfiguration
    .createProcessEngineConfigurationFromInputStream(inputStream)
    .buildProcessEngine()

对于所有 activiti.cfg.xml 文件,流程引擎将以 Spring 方式构建:首先创建 Spring 应用程序上下文,然后从该应用程序上下文获取流程引擎。

所有服务都是无状态的。 这意味着您可以轻松地在集群中的多个节点上运行 Camunda Platform,每个节点都访问同一个数据库,而不必担心哪台机器实际执行了先前的调用。 对任何服务的任何调用都是幂等的,无论在何处执行。

RepositoryService 可能是使用 Camunda 引擎时需要的第一个服务。 该服务提供管理和操作部署和流程定义的操作。 这里不再赘述,流程定义是 BPMN 2.0 流程的 Java 对应部分。 它是流程每个步骤的结构和行为的表示。 部署是引擎内的打包单元。 部署可以包含多个 BPMN 2.0 XML 文件和任何其他资源。 一次部署中包含的内容由开发人员选择。 它的范围可以从单个流程 BPMN 2.0 XML 文件到整个流程包和相关资源(例如,部署“hr-processes”可以包含与 hr 流程相关的所有内容)。 RepositoryService 允许部署此类包。 部署部署意味着将其上传到引擎,所有流程在存储到数据库之前都会在引擎中进行检查和解析。 从那时起,系统就知道部署,并且现在可以启动部署中包含的任何进程。

此外,该服务允许:

  • 查询引擎已知的部署和流程定义。
  • 暂停和激活流程定义。 挂起意味着不能对它们进行进一步的操作,而激活则是相反的操作。
  • 检索各种资源,例如部署中包含的文件或引擎自动生成的流程图。

虽然 RepositoryService 涉及静态信息(即不会改变或至少不会改变很多的数据),但 RuntimeService 却恰恰相反。 它涉及启动流程定义的新流程实例。 如上所述,流程定义定义流程中不同步骤的结构和行为。 流程实例是此类流程定义的一次执行。 对于每个流程定义,通常有许多实例同时运行。 RuntimeService 也是用于检索和存储流程变量的服务。 这是特定于给定流程实例的数据,并且可由流程中的各种构造使用(例如,独占网关通常使用流程变量来确定选择哪个路径来继续流程)。 RuntimeService 还允许查询流程实例和执行。 执行是 BPMN 2.0 的“代币”概念的体现。 基本上,执行是一个指向流程实例当前所在位置的指针。 最后,每当流程实例等待外部触发器并且流程需要继续时,就会使用 RuntimeService。 流程实例可以有各种等待状态,并且该服务包含各种操作来向实例发出“信号”,表明已收到外部触发器并且流程实例可以继续。

Task是需要由系统的实际用户执行的,是流程引擎的核心。 围绕Task的所有内容都分组在 TaskService 中,例如

  • 查询分配给用户或组的任务。
  • 创建新的独立任务。 这些是与流程实例无关的任务。
  • 操纵将任务分配给哪个用户或哪些用户以某种方式参与该任务。
  • 领取并完成任务。 声明意味着某人决定成为该任务的受让人,这意味着该用户将完成该任务。 完成意味着“完成任务的工作”。 通常,这是填写某种表格。

IdentityService 非常简单。 它允许管理(创建、更新、删除、查询……)组和用户。 重要的是要了解核心引擎实际上不会在运行时对用户进行任何检查。 例如,可以将任务分配给任何用户,但引擎不会验证系统是否已知该用户。 这是因为该引擎还可以与 LDAP、Active Directory 等服务结合使用。

FormService 是一项可选服务。 这意味着 Camunda 引擎可以在没有它的情况下完美使用,而不会牺牲任何功能。 该服务引入了启动表单和任务表单的概念。 启动表单是在流程实例启动之前向用户显示的表单,而任务表单是在用户想要完成任务时显示的表单。 您可以在 BPMN 2.0 流程定义中定义这些表单。该服务以一种易于使用的方式公开这些数据。 但同样,这是可选的,因为表单不需要嵌入到流程定义中。

HistoryService 公开了引擎收集的所有历史数据。 执行流程时,引擎可以保留大量数据(这是可配置的),例如流程实例启动时间、谁执行了哪些任务、完成任务需要多长时间、每个流程实例遵循哪条路径等 . 该服务主要公开访问此数据的查询功能。

编写自定义应用程序时通常不需要 ManagementService。 它允许检索有关数据库表和表元数据的信息。 此外,它还公开了作业的查询功能和管理操作。 作业在引擎中用于各种用途,例如计时器、异步延续、延迟挂起/激活等。稍后,将更详细地讨论这些主题。

FilterService 允许创建和管理过滤器。 过滤器是像任务查询一样存储的查询。 例如,任务列表使用过滤器来过滤用户任务。

ExternalTaskService 提供对外部任务实例的访问。 外部任务表示在外部处理且独立于流程引擎的工作项。

CaseService 类似于 RuntimeService,但用于案例实例。 它涉及启动案例定义的新案例实例并管理案例执行的生命周期。 该服务还用于检索和更新案例实例的流程变量。

DecisionService 允许评估部署到引擎的决策。 它是评估独立于流程定义的业务规则任务中的决策的替代方法。

Query API

要从引擎查询数据有多种可能性: - Java 查询 API:用于查询引擎实体(如 ProcessInstances、任务等)的流畅 Java API。 - REST 查询 API:用于查询引擎实体(如 ProcessInstances、任务等)的 REST API。 - 本机查询:如果查询 API 缺乏您需要的可能性(例如 OR 条件),则提供自己的 SQL 查询来检索引擎实体(例如 ProcessInstances、任务等)。 - 自定义查询:使用完全自定义的查询和自己的 MyBatis 映射来检索自己的值对象或将引擎与域数据连接起来。 - SQL 查询:将数据库 SQL 查询用于报告等用例。

推荐的方法是使用查询 API 之一。

Java 查询 API 允许使用流畅的 API 编写完全类型安全的查询。 您可以向查询添加各种条件(所有这些条件都作为逻辑 AND 一起应用)和精确的一个排序。 以下代码显示了一个示例:

List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("kermit")
.processVariableValueEquals("orderId", "0815")
.orderByDueDate().asc()
.list();

You can find more information on this in the Java Docs .

Query Maximum Results Limit

在不限制最大结果数的情况下查询结果或者查询大量结果可能会导致内存消耗较高,甚至出现内存不足的异常。 借助查询最大结果限制,您可以限制最大结果数。

此限制仅在以下情况下强制执行: - 经过身份验证的用户执行查询 - 查询API直接调用e。 G。 通过 REST API(通过委托代码在流程中不强制执行)

Forbidden 禁止行为

  • 使用 #list() 方法执行具有无限数量结果的查询
  • 执行超出配置的最大结果限制的分页查询
  • 执行基于查询的同步操作,影响的实例数量超过最大结果限制(请改用批量操作)

Allowed

  • 使用 Query#unlimitedList 方法执行查询
  • 执行分页查询,最大结果数小于或等于最大结果限制
  • 执行本机查询,因为它无法通过 REST API 或 Web 应用程序访问,因此不太可能被利用

Limitations 限制使用

  • 通过 REST API 执行统计查询
  • 通过Webapps(私有API)执行被调用实例查询

Custom Identity Service Queries

当您提供... - 通过实现 ReadOnlyIdentityProvider 或 WritableIdentityProvider 接口来实现自定义身份提供程序 - 以及身份服务查询的专用实现(例如 GroupQuery、TenantQuery、UserQuery)

确保在调用 Query#unlimitedList 时返回所有结果,没有任何限制。 检索无限列表的可能性对于确保 REST API 正常工作非常重要,因为一些端点依赖于检索无限结果。

Paginated Queries 分页查询

分页允许配置查询检索到的最大结果以及第一个结果的位置(索引)。

请看下面的例子:

List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("kermit")
.processVariableValueEquals("orderId", "0815")
.orderByDueDate().asc()
.listPage(20, 50);

上面显示的查询从索引 20 的结果开始检索 50 个结果。

OR Queries

查询 API 的默认行为将过滤条件与 AND 表达式链接在一起。 OR 查询支持构建查询,其中过滤条件与 OR 表达式链接在一起。

注意: - 此功能仅适用于任务和流程实例查询(运行时和历史记录)。 - 以下方法不能应用于 OR 查询:orderBy…()、initializeFormKeys()、withCandidateGroups()、withoutCandidateGroups()、withCandidateUsers()、withoutCandidateUsers()。

调用 or() 后,可能会出现一系列多个过滤条件。 每个过滤条件都通过 OR 表达式链接在一起。 endOr() 的调用标志着 OR 查询的结束。 调用这两个方法相当于将过滤条件放在括号中。

List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("John Munda")
.or()
    .taskName("Approve Invoice")
    .taskPriority(5)
.endOr()
.list();

上面的查询检索分配给“John Munda”并同时命名为“Approve Invoice”或赋予第五级优先级的所有任务(受让人 =“John Munda”AND(名称 =“Approve Invoice”OR 优先级 = 5), 连接范式)。

在内部,查询被转换为以下 SQL 查询(稍微简化):

SELECT DISTINCT *
FROM   act_ru_task RES
WHERE  RES.assignee_ = 'John Munda'
    AND ( Upper(RES.name_) = Upper('Approve Invoice')
            OR RES.priority_ = 5 );

可以一次使用任意数量的 OR 查询。 当构建的查询不仅包含单个 OR 查询,还包含与 AND 表达式链接在一起的过滤条件时,OR 查询将通过前导 AND 表达式附加到条件链。 与变量相关的过滤条件可以在同一 OR 查询中多次应用:

List<Task> tasks = taskService.createTaskQuery()
.or()
    .processVariableValueEquals("orderId", "0815")
    .processVariableValueEquals("orderId", "4711")
    .processVariableValueEquals("orderId", "4712")
.endOr()
.list();

除了与变量相关的过滤条件之外,此行为有所不同。 每当在查询中多次使用非变量过滤条件时,仅使用最后应用的值:

List<Task> tasks = taskService.createTaskQuery()
.or()
    .taskCandidateGroup("sales")
    .taskCandidateGroup("controlling")
.endOr()
.list();

注意: 在上面显示的查询中,过滤条件 taskCandidateGroup 的值“sales”被值“controlling”替换。 为了避免这种行为,可以使用尾随 …In 的过滤条件,例如: - taskCandidateGroupIn() - tenantIdIn() - processDefinitionKeyIn()

REST Query API

Java 查询 API 也作为 REST 服务公开,有关详细信息,请参阅 REST 文档。

Native Queries

有时您需要更强大的查询,例如使用 OR 运算符的查询或无法使用查询 API 表达的限制。 对于这些情况,我们引入了本机查询,它允许您编写自己的 SQL 查询。 返回类型由您使用的查询对象定义,并且数据被映射到正确的对象,例如任务、流程实例、执行等。由于查询将在数据库中触发,因此您必须使用表和列名称,因为它们 在数据库模式中定义。 这需要一些关于内部数据结构的知识,建议谨慎使用本机查询。 可以通过 API 检索表名称,以保持尽可能小的依赖关系。

List<Task> tasks = taskService.createNativeTaskQuery()
.sql("SELECT * FROM " + managementService.getTableName(Task.class) + " T WHERE T.NAME_ = #{taskName}")
.parameter("taskName", "aOpenTask")
.list();

long count = taskService.createNativeTaskQuery()
.sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T1, "
        + managementService.getTableName(VariableInstanceEntity.class) + " V1 WHERE V1.TASK_ID_ = T1.ID_")
.count();

Custom Queries

出于性能原因,有时可能不希望查询引擎对象,而是查询一些自己的值或从不同表收集数据的 DTO 对象 - 可能包括您自己的域类。

SQL Queries

表格布局非常简单 - 我们致力于使其易于理解。 因此,可以进行 SQL 查询,例如报告用例。 只要确保您不会在完全不知道自己在做什么的情况下更新表格,从而弄乱引擎数据。