Getting Started with Activiti Core 7.0.0.Beta1(翻译)

Posted 山河已无恙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Getting Started with 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/ 中。对于本示例,我们定义了以下流程:
在这里插入图片描述

我们正在使用 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-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 😕/gitter.im/Activiti/Activiti7 ? utm_source = share-link & utm_medium = link & utm_campaign = share-link 。](https 😕/gitter.im/Activiti/Activiti7 ? utm_source = share-link & utm_medium = link & utm_campaign = share-link 。)

更多的博客文章将介绍运行时管理 API 以及如何调整这些示例以在我们新的 Activiti Cloud 方法中执行。

以上是关于Getting Started with Activiti Core 7.0.0.Beta1(翻译)的主要内容,如果未能解决你的问题,请参考以下文章

Getting Started with Erlang

Getting Started with Matplotlib

Getting started with roswtf

Getting Started with LLVM

01Getting Started---Getting Started with ASP.NET Web API 2入门WebApi2

Getting started with Chrome Dev Editor