Activiti Core 7.0.0.Beta1 入门

Activiti Core 7.0.0.Beta1 入门

我们刚刚向Maven Central发布了Activiti CoreActiviti Cloud 7.0.0.Beta1,我们想重点介绍新的Process 和 Task Runtime API。

创建新 API 的目的很明确,旨在满足以下要求:

  • 为我们的云方法提供清晰的路径
  • 隔离内部和外部 API 以提供向前的向后兼容性
  • 通过遵循单一职责方法提供未来的模块化路径
  • 减少旧版本 API 的混乱
  • 将安全和身份管理作为一等公民
  • 减少常见用例的价值实现时间,在这些用例中您希望依赖流行框架提供的约定
  • 提供底层服务的替代实现
  • 使社区能够在尊重既定合同的同时进行创新

我们尚未弃用旧 API,因此您仍然可以*使用它,但我们强烈建议使用新 API 以获得长期支持。

此 API 处于测试阶段,这意味着我们可能会在 GA 发布之前对其进行更改和完善。我们将感谢我们从社区用户那里获得的所有反馈,如果您想参与该项目,请与我们联系。

是时候让我们接触几个示例项目了。

任务运行时 API(TaskRuntime API)

如果您正在构建业务应用程序,为您组织中的用户和组创建任务可能会很方便。

该任务运行时API是来帮助你。

你可以从 GitHub 克隆这个例子:https://github.com/Activiti/activiti-examples

本节的代码可以在activiti-api-basic-task-example maven 模块中找到。

如果您在 Spring Boot 2 应用程序中运行,您只需要添加 activiti-spring-boot-starter 依赖项和一个 DB 驱动程序,您可以使用 H2 进行内存存储。

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/pom.xml#L45

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

我们建议使用我们的 BOM(物料清单

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/pom.xml#L30

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-dependencies</artifactId>
            <version>7.0.0.Beta1</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

现在让我们切换到我们的 DemoApplication.class
https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L25

然后你就可以使用 TaskRuntime

@Autowired
private TaskRuntime taskRuntime;

将 bean 注入应用程序后,您应该能够创建任务并与任务进行交互。

public interface TaskRuntime {
  TaskRuntimeConfiguration configuration();
  Task task(String taskId);
  Page tasks(Pageable pageable);
  Page tasks(Pageable pageable, GetTasksPayload payload);
  Task create(CreateTaskPayload payload);
  Task claim(ClaimTaskPayload payload);
  Task release(ReleaseTaskPayload payload);
  Task complete(CompleteTaskPayload payload);
  Task update(UpdateTaskPayload payload);
  Task delete(DeleteTaskPayload payload);
  ...
}

例如,您可以通过执行以下操作来创建任务:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L45

taskRuntime.create(
            TaskPayloadBuilder.create()
                .withName("First Team Task")
                .withDescription("This is something really important")
                .withGroup("activitiTeam")
                .withPriority(10)
           .build());

此任务仅对属于activitiTeam用户所有者(当前登录的用户)可见

为了处理安全性、角色和组,我们依赖 Spring Security 模块。因为我们在 Spring Boot 应用程序中,所以我们可以使用 UserDetailsS​​ervice 来配置可用用户及其各自的角色。我们目前正在@Configuration类中执行此操作:

[https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples /DemoApplicationConfiguration.java#L26](https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples /DemoApplicationConfiguration.java#L26)

这里需要注意的重要一点是,为了作为用户与 TaskRuntime API 交互,您需要具有角色: ACTIVITI_USER (Granted Authority: ROLE_ACTIVITI_USER)

在与 REST 端点交互时,授权机制将设置当前登录的用户,但为了示例,我们使用了一个实用程序类
[https://github.com/Activiti/activiti-examples/blob/master/activiti -api-basic-task-example/src/main/java/org/activiti/examples/SecurityUtil.java#L26](https://github.com/Activiti/activiti-examples/blob/master/activiti -api-basic-task-example/src/main/java/org/activiti/examples/SecurityUtil.java#L26)
允许我们在上下文中设置手动选择的用户。请注意,除非您正在尝试并且想在不通过 REST 端点的情况下更改用户,否则您永远不应该这样做。查看“网络”示例以查看更多根本不需要此实用程序类的真实场景。

示例中要强调的最后一件事是任务事件侦听器注册https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L89

@Bean
public TaskRuntimeEventListener taskAssignedListener() {
  return taskAssigned
           -> logger.info(
                 ">>> Task Assigned: '"
                + taskAssigned.getEntity().getName()
                +"' We can send a notification to the assignee: "
                + taskAssigned.getEntity().getAssignee());
}

您可以根据需要注册任意数量的 TaskRuntimeEventListener。这将使您的应用程序能够收到由服务触发的运行时事件的通知。

进程运行时 API(ProcessRuntime API)

以类似的方式,如果您想开始使用 ProcessRuntime API,您需要包含与以前相同的依赖项。我们的目标是在未来提供更多的灵活性独立的运行时,但现在同一个 Spring Boot Starter 提供 TaskRuntimeProcessRuntime API

本节的代码可以在“activiti-api-basic-process-example” maven 模块中找到。

public interface ProcessRuntime {
  ProcessRuntimeConfiguration configuration();
  ProcessDefinition processDefinition(String processDefinitionId);
  Page processDefinitions(Pageable pageable);
  Page processDefinitions(Pageable pageable,
              GetProcessDefinitionsPayload payload);
  ProcessInstance start(StartProcessPayload payload);
  Page processInstances(Pageable pageable);
  Page processInstances(Pageable pageable,
              GetProcessInstancesPayload payload);
  ProcessInstance processInstance(String processInstanceId);
  ProcessInstance suspend(SuspendProcessPayload payload);
  ProcessInstance resume(ResumeProcessPayload payload);
  ProcessInstance delete(DeleteProcessPayload payload);
  void signal(SignalPayload payload);
  ...
}

与 TaskRuntime API 类似,为了与 ProcessRuntime API 交互,当前登录的用户需要具有“ACTIVITI_USER”角色。

首先,让我们自动装配我们的 ProcessRuntime
https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L32

@Autowired
private ProcessRuntime processRuntime;
@Autowired
private SecurityUtil securityUtil;

和以前一样,我们需要我们的 SecurityUtil 助手来定义我们正在与我们的 API 交互的用户。

现在我们可以开始与 ProcessRuntime 交互:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L47


Page processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
logger.info("> Available Process definitions: " +  processDefinitionPage.getTotalItems());
for (ProcessDefinition pd : processDefinitionPage.getContent()) {
  logger.info("\t > Process definition: " + pd);
}

流程定义需要放在/src/main/resources/processes/ 中。对于本示例,我们定义了以下流程:
Activiti Core 7.0.0.Beta1 入门

我们正在使用 Spring 调度功能每秒启动一个进程,从数组中获取随机值以进行处理:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L67

@Scheduled(initialDelay = 1000, fixedDelay = 1000)
public void processText() {
  securityUtil.logInAs("system");
  String content = pickRandomString();
  SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
  logger.info("> Processing content: " + content
                    + " at " + formatter.format(new Date()));
  ProcessInstance processInstance = processRuntime
                  .start(ProcessPayloadBuilder
                       .start()
                       .withProcessDefinitionKey("categorizeProcess")
                       .withProcessInstanceName("Processing Content: " + content)
                       .withVariable("content", content)
                       .build());
  logger.info(">>> Created Process Instance: " + processInstance);
}

和以前一样,我们使用ProcessPayloadBuilder以流畅的方式参数化我们想要启动哪个流程以及使用哪些流程变量。

现在,如果我们回顾流程定义,您会发现 3 个服务任务。为了提供这些服务任务的实现,您需要定义连接器:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L81

@Bean
public Connector processTextConnector() {
  return integrationContext -> {
      Map inBoundVariables = integrationContext.getInBoundVariables();
      String contentToProcess = (String) inBoundVariables.get("content")
     // Logic Here to decide if content is approved or not
     if (contentToProcess.contains("activiti")) {
        logger.info("> Approving content: " + contentToProcess);
        integrationContext.addOutBoundVariable("approved",true);
     } else {
        logger.info("> Discarding content: " + contentToProcess);
        integrationContext.addOutBoundVariable("approved",false);
     }
    return integrationContext;
  };
}

这些连接器使用 Bean名称自动连接到ProcessRuntime,在本例中为“processTextConnector ”。这个 bean 名称是从我们流程定义中的serviceTask元素的implementation属性中提取的:
https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-process-example/src/main/resources/processes/categorize-content.bpmn20.xml#L22

<bpmn:serviceTask id="Task_1ylvdew" name="Process Content" implementation="processTextConnector">

这个新的连接器接口是JavaDelegates的自然演变,新版本的Activiti Core将尝试通过将它们包装在连接器实现中来重用您的 JavaDelegates:

public interface Connector {
  IntegrationContext execute(IntegrationContext integrationContext);
}

连接器接收带有流程变量的IntegrationContext并返回修改后的IntegrationContext以及需要映射回流程变量的结果。

在前面的示例中,连接器实现正在接收一个“内容”变量并根据内容处理逻辑添加一个“批准”变量。

在这些连接器中,您可能会包含系统到系统调用,例如 REST 调用和基于消息的交互。这些交互往往变得越来越复杂,因此我们将在未来的教程中看到如何从ProcessRuntime(云连接器)上下文之外运行中提取这些连接器,以解耦此类外部交互的责任。ProcessRuntime范围。

检查 maven 模块activiti-api-spring-integration-example以获得更高级的示例,使用 Spring Integrations基于文件轮询器启动进程。

完整示例

您可以找到同时使用ProcessRuntimeTaskRuntime API来自动化以下过程的示例:
Activiti Core 7.0.0.Beta1 入门
节的代码可以在“activiti-api-basic-full-example” maven 模块中找到。

作为 ProcessRuntime only示例,这也对一些输入内容进行了分类,但在这种情况下,流程依赖于人类演员来决定是否批准内容。我们有一个计划任务,它每 5 秒创建一次新的流程实例,还有一个模拟用户检查是否有可用的任务可以处理。
https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-full-example/src/main/java/org/activiti/examples/DemoApplication.java#L63

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-full-example/src/main/java/org/activiti/examples/DemoApplication.java#L85

所述UserTask创建一组potentialOwners,在这个例子中,“activitiTeam ”基团。但在这种情况下,我们不会像第一个示例那样手动创建任务。流程实例在每次启动流程时为我们创建任务。

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-full-example/src/main/resources/processes/categorize-human-content.bpmn20.xml#L38

<bpmn:userTask id="Task_1ylvdew" name="Process Content">
      <bpmn:incoming>SequenceFlow_09xowo4</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_1jzbgkj</bpmn:outgoing>
      <bpmn:potentialOwner>
        <bpmn:resourceAssignmentExpression>
          <bpmn:formalExpression>activitiTeam</bpmn:formalExpression>
        </bpmn:resourceAssignmentExpression>
      </bpmn:potentialOwner>
    </bpmn:userTask>

属于该组的用户将能够声明并处理该任务。

我们鼓励您运行这些示例并对其进行试验,如果您有疑问或发现问题,请与我们联系。

概括

在这篇博文中,我们看到了如何开始使用来自新 Activiti Core Beta1项目的新ProcessRuntimeTaskRuntime API。

我们建议您查看Activiti示例存储库,以获取更多示例:
[https : //github.com/Activiti/activiti-examples](https : //github.com/Activiti/activiti-examples)

帮助我们编写更多这些示例可能是一个非常好的初始社区贡献。如果您有兴趣,请与我们联系,我们非常乐意为您提供指导。

如果您对这些示例和教程有任何疑问或反馈,请随时通过 Gitter 与我们联系:[https

上一篇:Spring Boot 整合 Activiti 6.0.0 工作流引擎开发


下一篇:工作流Activiti框架中表单的使用!详细解析内置表单和外置表单的渲染