Activity7入门学习(二)

官网地址:https://activiti.gitbook.io/activiti-7-developers-guide/getting-started/getting-started-activiti-core

Getting Started - Activiti Core

Getting Started with Activiti Core Runtime APIs

新api的创建有明确的目的,以满足以下需求:
.为我们的云方法提供一条清晰的路径
.隔离内部和外部api以提供向前的向后兼容性
.通过遵循单一责任方法,提供通向模块化的未来路径
.减少以前版本api的混乱
.包括安全和身份管理作为一级公民
.在您希望依赖流行框架提供的约定的常用用例中,减少实现价值的时间
.提供基础服务的替代实现
.让社区在尊重既定契约的同时进行创新
我们没有弃用旧的API,所以您仍然可以自由使用它,但我们强烈建议使用新的API以获得长期支持。
这个API还在测试阶段,这意味着我们可能会在GA发布之前对它进行修改和润色。我们将感谢所有的反馈,我们可以从我们的社区用户,如果你想参与到该项目,请与我们联系。
是时候亲自动手做几个示例项目了。

TaskRuntime API

如果您正在构建业务应用程序,为组织中的用户和组创建task可能会很方便。
TaskRuntime api可以帮助您。
你可以在这里找到一些基本的例子(api-example模块).
本节的代码可以在“activity -api-basic-task-example”maven模块中找到。
如果你在Spring Boot 2应用程序中运行,你只需要添加activity - Spring - Boot -starter依赖和一个DB驱动程序,你可以使用H2作为内存存储。

https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-task-example/pom.xml
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

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

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

注意:要在这里检查哪个是最新的版本(https://github.com/Activiti/Activiti/releases/tag/7.6.1)

现在让我们切换到DemoApplication.class:
然后您就可以使用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/blob/develop/activiti-examples/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L60-L65

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

此任务仅对属于activitiTeam和所有者(当前登录的用户)的用户可见。
您可能已经注意到,可以使用TaskPayloadBuilder来参数化将要以一种流畅的方式发送到TaskRuntime的信息。
为了处理安全、角色和组,我们依赖Spring安全模块。因为我们在Spring Boot应用程序中,所以我们可以使用UserDetailsService来配置可用的用户及其各自的组和角色。
我们目前在@Configuration类中这样做:(https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplicationConfiguration.java#L40-L62)

这里需要注意的重要一点是,为了以用户的身份与TaskRuntime API交互,您需要拥有角色:actiti_user(授予的权限:role_actiti_user)。

在与REST端点交互时,授权机制将设置当前登录的用户,但为了示例的目的,我们使用的是实用程序类SecurityUtil.java(https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-task-example/src/main/java/org/activiti/examples/SecurityUtil.java)这允许我们在上下文中设置手动选择的用户。
请注意,除非您正在进行尝试,并且希望在不通过REST端点的情况下更改用户,否则永远不应该这样做。查看“web”示例,了解更多不需要此实用程序类的实际场景。
最后需要强调的是任务事件监听器的注册:(https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L103-L108)

@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。这将使您的应用程序能够在服务触发运行时事件时得到通知。

ProcessRuntime API

以类似的方式,如果您想开始使用ProcessRuntime api,您需要包括与以前相同的依赖项。我们的目标是在未来提供更多的灵活性和独立的运行时,
但目前同一个Spring Boot Starter同时提供TaskRuntime和ProcessRuntime API。本节的代码可以在“activity -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交互,当前登录的用户需要具有角色“actiti_user”。

首先,让我们@Autowired我们的ProcessRuntime:(https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L48-L52)

@Autowired
private ProcessRuntime processRuntime;

@Autowired
private SecurityUtil securityUtil;

与以前一样,我们需要securityyutil帮助器来定义与api交互的用户。

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

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

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 Scheduling功能来启动一个进程,每一秒从一个数组中拾取随机值。(https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-process-example/src/main/java/org/activiti/examples/DemoApplication.java#L71-L91)

@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个服务任务。为了为这些服务任务提供实现,你需要定义Connectors:

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

 

@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元素的实现属性中获取的:(https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-process-example/src/main/resources/processes/categorize-content.bpmn20.xml#L22)

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

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

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

连接器接收一个带有流程变量的IntegrationContext,并返回一个经过修改的IntegrationContext,其中包含需要映射回流程变量的结果。
在前面的示例中,连接器实现正在接收一个“content”变量,并根据内容处理逻辑添加一个“approved”变量。
在这些连接器中,您可能包括系统到系统的调用,例如REST调用和基于消息的交互。这些交互往往变得越来越复杂,因此,
我们将在以后的教程中看到如何从ProcessRuntime(云连接器)上下文之外的运行中提取这些连接器,以分离ProcessRuntime作用域之外的这些外部交互的责任.
查看maven模块activity -api- Spring -integration-example,查看使用Spring integration基于文件轮询器启动进程的更高级示例。

Full Example

你可以找到一个使用ProcessRuntime和TaskRuntime api来自动化以下过程的例子:本节的代码可以在“activity -api-basic-full-example”maven模块中找到。
作为仅使用ProcessRuntime的示例,这也对一些输入内容进行了分类,但在本例中,流程依赖于一个Human Actor来决定是否批准内容。和前面一样,
我们有一个计划任务,它每5秒创建一个新的流程实例,还有一个模拟用户检查是否有可用的任务。

https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-full-example-bean/src/main/java/org/activiti/examples/DemoApplication.java#L80-L100

https://github.com/Activiti/Activiti/blob/develop/activiti-examples/activiti-api-basic-full-example-bean/src/main/java/org/activiti/examples/DemoApplication.java#L102-L137

UserTask被创建给一组潜在的所有者,在本例中是“actititeam”组。但在本例中,我们没有像第一个示例中那样手动创建任务。流程实例在每次流程启动时为我们创建任务。
属于此组的用户将能够声明并处理该任务。

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

<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>

我们鼓励您运行这些示例并尝试使用它们,如果您有问题或发现问题,请与我们联系。

Summary

在本教程中,我们已经看到了如何开始使用来自新的Activiti Core Beta项目的新的ProcessRuntime和TaskRuntime API。
我们建议您查看Activiti Examples库,获取更多示例:https://github.com/Activiti/Activiti/tree/develop/activiti-examples

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

一如既往,欢迎通过Gitter与我们联系:https://gitter.im/Activiti/Activiti7

更多的博客文章将介绍Runtime Admin api,以及如何调整这些示例,以便在我们新的Activiti Cloud方法中执行。

posted @ 2022-12-13 21:43  WK_BlogYard  阅读(396)  评论(0编辑  收藏  举报