Activity7学习入门(六)

官网地址:https://activiti.gitbook.io/activiti-7-developers-guide/components/activiti-cloud-application

Activiti Cloud Application

Activiti云应用是由Activiti云核心构建块集组成的。这些构建模块是:
Activiti Cloud Runtime Bundle:为业务资产(如业务流程、任务、决策表、决策树等)提供执行运行时。
Activiti Cloud Connectors:提供与外部系统的双向连接。
Activiti Cloud Audit Service:提供审计跟踪功能,从或多个运行时收集信息(事件)。
Activiti Cloud Query Service: 提供对一个或多个运行时生成的信息的读访问。
Activiti Cloud Notification Service:与查询服务一起,通知服务支持关于应用程序状态的订阅和推送通知的核心构建块。

这些核心构建块将公开REST和基于消息的端点,以支持特定于领域的应用程序与它们交互。核心构建块之间的通信是使用Spring Cloud Stream来使用命令操作或发出表示内部流程引擎操作的事件来实现的异步通信(默认情况下使用RabbitMQ绑定器)。

Activiti Cloud Runtime Bundle

运行时包是流程引擎的云版本。如果您曾经将Activiti(流程引擎)作为服务公开,那么您就是在定义一个Runtime Bundle。
但是关于Runtime bundle你还需要知道一些额外的事情:
.Activiti Cloud上下文中的Runtime bundle表示流程引擎的无状态实例,该实例负责执行一组不可变的流程定义。
.您不能将新的流程定义部署到运行时Bundle中,相反,如果您想更新流程定义,您可以创建运行时Bundle的一个新的不可变版本.
.运行时包公开了一个(同步)REST和(异步)基于消息的API来与它们交互。
.运行时bundle使用内部ActivitiEventListener接口的一组实现发出事件(以“触发并忘记”的方式)(监听内部Process Engine事件,并将它们转换为包含事务内部生成的所有事件的消息。)
.默认情况下,在执行服务任务(BPMN)时,运行时包将发出集成事件来执行系统到系统的集成。Activiti云连接器将接收这些集成事件,以执行系统到系统的集成.

 

 REST APIs (HAL)

Runtime Bundles 使用以下用户(actiti_user角色)端点公开一个REST API:

ProcessDefinitionController.java
/v1/process-definitions
/v1/process-definitions/{id}/meta
/v1/process-instances

还有以下admin (actiti_admin角色)端点:

/admin/v1/process-definitions

/admin/v1/process-instances

/admin/v1/tasks

(Async) Command Based Interactions((异步)基于命令的交互)

在新的Java Core API层中,命令被定义为有效负载。这些负载包含执行流程引擎内部实现的不同操作的信息,如果执行生成了数据,它们将返回Result。
当消息端点执行这些命令时,结果将被发送到不同的队列。
这些命令由CommandEndpoint处理,它将每个命令的操作委托给更具体的executor
命令 Payloads (implements Payload)
Process Related Payloads:
StartProcessPayload:
SuspendProcessPayload:
ResumeProcessPayload:
SignalPayload:
SetProcessVariablesPayload:
DeleteProcessPayload:
RemoveProcessVariablesPayload:
ClaimTaskPayload:
ReleaseTaskPayload:
CompleteTaskPayload:

DeleteTaskPayload:
UpdateTaskPayload:

Message Enabled(消息)

通过设计,运行时Bundle可以使用和产生(异步)消息。这是通过使用Spring Cloud Streams来使用命令操作或发出表示内部流程引擎操作的事件来实现的。
注意,根据设计,运行时Bundle并没有内置WebSockets/Push Notifications。
事件由流程引擎使用消息队列发出,因此外部组件可以对它们作出反应。所有这些事件都实现了org. activity .services.core.model.events. processengineevent接口。
与BPMN活动相关的事件可以在Java Core API activiti-api-process-model模块中找到。

BPMNActivityStartedEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-process-model/src/main/java/org/activiti/api/process/model/events/BPMNActivityStartedEvent.java
BPMNActivityCompletedEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-process-model/src/main/java/org/activiti/api/process/model/events/BPMNActivityCompletedEvent.java
BPMNActivityCancelledEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-process-model/src/main/java/org/activiti/api/process/model/events/BPMNActivityCancelledEvent.java
SequenceFlowEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-process-model/src/main/java/org/activiti/api/process/model/events/SequenceFlowEvent.java

我们为变量相关的操作共享了事件,可以在这里找到(activiti-api-model-shared)

VariableCreatedEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-model-shared/src/main/java/org/activiti/api/model/shared/event/VariableCreatedEvent.java
VariableUpdatedEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-model-shared/src/main/java/org/activiti/api/model/shared/event/VariableUpdatedEvent.java
VariableDeletedEvent:https://github.com/AlfrescoArchive/activiti-api/blob/develop/activiti-api-model-shared/src/main/java/org/activiti/api/model/shared/event/VariableDeletedEvent.java

可以在这里找到与Process Runtime相关的事件(activiti-api-process-runtime)

ProcessStartedEvent
ProcessCompletedEvent
ProcessCancelledEvent
ProcessResumedEvent
ProcessSuspendedEvent
ProcessCreatedEvent

与任务相关的事件可以在这里找到(activiti-api-task-runtime)
TaskCreatedEvent
TaskAssignedEvent
TaskCompletedEvent
TaskSuspendedEvent
TaskActivatedEvent
TaskCandidateGroupAddedEvent
TaskCandidateGroupRemovedEvent
TaskCandidateUserAddedEvent
TaskCandidateUserRemovedEvent
还没补充的类
ActivityCompensateEvent
ProcessCompletedErrorEvent
Runtime Bundle Data Types(运行时包数据类型)
运行时包工作并公开以下基于新的Java Core API模型包的数据类型:
.activiti-api-model-shared
.activiti-api-process-model
.activiti-api-task-model
以及云扩展类型:
.activiti-cloud-api-model-shared
.activiti-cloud-api-process-model
.activiti-cloud-api-task-model
Requirements(需求)
运行时bundle需要以下基础设施服务列表:

.SSO / IDM service for handling Security and User/Groups resolutions(SSO / IDM服务用于处理安全性和用户/组解析)
.Message Broker to emit and consume messages(消息代理来发出和使用消息)
.Database to store the state of the process instances and tasks(数据库来存储流程实例和任务的状态)

Security
除了通过外部授权系统提供的端点级授权(在属性文件中配置Keycloak的情况下)之外,
运行时包中的单个流程定义(以及隐式流程实例)可以应用ACLs 。它们通过属性文件应用,格式如下:

activiti.cloud.security.user.testuser.runtime-bundle.policy.read=process_pool1,ProcessWithVariables
activiti.cloud.security.group.hr.runtime-bundle.policy.write=process_pool1,ProcessWithVariables,SimpleProcess,ProcessWithVariables2,ProcessWithBoundarySignal

或者可以使用环境变量,例如:

ACTIVITI_CLOUD_SECURITY_USER_HRUSER_RBMYAPP_POLICY_WRITE=SimpleProcess 
ACTIVITI_CLOUD_SECURITY_GROUP_HR_RBMYAPP_POLICY_WRITE=SimpleProcess
ACTIVITI_CLOUD_SECURITY_GROUP_TESTGROUP_RBMYAPP_POLICY_WRITE=*

Source Code & Docker Image

在这里(activiti-cloud-runtime-bundle-service),您可以找到一个运行时Bundle示例,您可以使用它作为构建特定于域的运行时Bundle的起点。
该项目是使用(activiti-cloud-starter-runtime-bundle)

sourceCode:https://github.com/Activiti/activiti-cloud-runtime-bundle-service

dockerImage:https://hub.docker.com/r/activiti/activiti-cloud-runtime-bundle/

Activiti Cloud Connectors

Activiti Cloud Connectors提供了一种可伸缩的方式来执行双向的系统与系统交互。它使业务流程能够以一种安全的方式与外部系统交互,而不影响流程运行时.
没有开发新的框架、协议或任何其他疯狂的东西来赋予Activiti云连接器生命
Activiti云连接器提供:
.一种映射和执行系统到系统交互的快速方法。
.灵活的配置,支持使用知名技术栈的高需求场景
.在相同的基础结构中版本化和维护多个连接器并使其运行的方法
.处理BPMN服务任务的默认方法
.在流程运行时中触发操作的统一方法
.(未来)进程间通信:发送/捕获/发送和接收消息
Cloud Connector as BPMN Service Task()
当流程定义文件中只定义属性实现时,云连接器是BPMN服务任务的默认实现。下面的部分将解释运行时包和云连接器如何交互。

Activiti Runtime Bundle side
运行时Bundle依赖Spring Cloud Streams将服务任务的执行委派给云连接器。一旦流程执行到达服务任务,集成请求消息将被发送到与相关服务任务的属性实现中定义的名称相同的动态绑定目的地。
例如,在下面的例子中,一条消息将被发送到目的地SendRewardToWinners。

<serviceTask id="serviceTaskSendReward" name="Tweet Winners" implementation="SendRewardToWinners" />

在发送集成请求之后,运行时Bundle将等待连接器在其工作完成后发送的集成结果。为了接收返回的集成结果,运行时Bundle将监听名为integrationResultsConsumer的输入通道。
运行时包启动器(activity -cloud-starter-runtime-bundle)将为integrationResultsConsumer通道带来以下配置:

spring.cloud.stream.bindings.integrationResultsConsumer.destination=integrationResult:${spring.application.name}
spring.cloud.stream.bindings.integrationResultsConsumer.contentType=application/json
spring.cloud.stream.bindings.integrationResultsConsumer.group=${ACT_RB_APP_NAME:my-runtime-bundle}

Cloud Connector side

为了实现作为服务任务的云连接器,我们需要:
.向连接器启动器添加一个依赖项:

<dependency>
  <groupId>org.activiti.cloud</groupId>
  <artifactId>activiti-cloud-starter-connector</artifactId>
</dependency>

.定义一个输入通道,使用Spring Cloud Stream @Input注释,来接收来自运行时Bundle的集成请求。例句:

public interface RewardMessageChannels {
    String REWARD_CONSUMER = "rewardConsumer";

    @Input(REWARD_CONSUMER)
    SubscribableChannel rewardConsumer();
}

.为上一步中定义的通道启用绑定

@Component
@EnableBinding(RewardMessageChannels.class)
public class SendRewardConnector {
...
}

.实现连接器业务逻辑,并将结果发送回Runtime Bundle

    @StreamListener(value = RewardMessageChannels.REWARD_CONSUMER)
    public void tweet(IntegrationRequest event) {

        // business logic goes here

        // build and send result back
        Map<String, Object> results = new HashMap<>();
        Message<IntegrationResult> message = IntegrationResultBuilder.resultFor(event, connectorProperties)
                .withOutboundVariables(results)
                .buildMessage();

        integrationResultSender.send(message);
    }

注意:IntegrationResultBuilder和IntegrationResultSender(自动连接)由activity -cloud-starter-connector提供。IntegrationResultSender将再次使用动态绑定的目的地,
以确保集成结果消息将被发送到正确的目的地:integrationResult:,其中TARGET_APPLICATION_NAME是发送初始集成请求的运行时bundle的名称。

Configuration

最终,我们需要配置上面声明的输入通道,以便仅为它打算接收的连接器接收集成请求。记住,集成请求被发送到由相关服务任务的属性实现定义的目的地。在我们的例子中,SendRewardToWinners。

spring.cloud.stream.bindings.rewardConsumer.destination=SendRewardToWinners
spring.cloud.stream.bindings.rewardConsumer.contentType=application/json
spring.cloud.stream.bindings.rewardConsumer.group=integration

重要的是:注意,云连接器和运行时Bundle可以(很可能会)运行在不同的Spring引导应用程序/容器中。

Error handling:

从7.1.0-M7版本开始,云连接器能够在执行过程中出错时通知Runtime Bundle。这可以通过两种方式实现:
.隐式地让连接器抛出异常。这将在将错误通知到Runtime Bundle之前触发Message Broker重试机制。
.显式使用IntegrationErrorBuilder和IntegrationErrorSender。这将不会触发Message Broker重试机制:错误通知将直接发送到Runtime包:

@StreamListener(value = RewardMessageChannels.REWARD_CONSUMER)
public void tweet(IntegrationRequest integrationRequest) {
    try {
        // business logic goes here
    } catch (Throwable error) {
        integrationErrorSender.send(
            IntegrationErrorBuilder.errorFor(integrationRequest, connectorProperties, error)
                .buildMessage());
    }
}

当Runtime包接收到连接器中发生错误的通知时,它将发送INTEGRATION_ERROR_RECEIVED事件以进行查询和审计。审计将此事件存储在其事件日志中,查询将相关服务任务的状态更新为错误状态。

Throwing BPMN Error Event

使用上面相同的机制,可以通过使用CloudBpmnError从云连接器抛出BPMN错误事件。调用连接器的服务任务范围内的流程中的任何BPMN Catch Error Event都可以捕获此BPMN错误。
重要的是:clouddbpmnerror中使用的错误代码应该与BPMN Catch error事件中使用的错误代码相匹配。

@StreamListener(value = RewardMessageChannels.REWARD_CONSUMER)
public void tweet(IntegrationRequest integrationRequest) {
    
    // business logic leading to a case that should throw a BPMN Error event
    
    CloudBpmnError error = new CloudBpmnError("BPMN_ERROR_CODE");
    integrationErrorSender.send(
        IntegrationErrorBuilder.errorFor(integrationRequest, connectorProperties, error)
            .buildMessage());
}

Activiti Cloud Query Service

查询服务使客户端应用程序能够获得流程和任务数据,而不直接进入运行时包。Query Service的设计目的是支持对一个或多个Runtime bundle生成的数据的高效查询机制。
与审计服务相反,查询服务获取事件并应用一些转换来存储状态。
该组件的设计目的是聚合来自一组相关运行时包的数据,允许使用者使用运行时包进行筛选。

 

 

 Specification

Endpoints

查询组件提供只读REST端点

Event Listeners

查询服务监听运行时包生成的事件,并将其转换为存储关于当前流程实例和任务执行的状态。此状态存储在一个为查询而优化的模式中,并且根据该组件的规范,可以使用不同的技术实现不同的实现。
我们的参考实现使用JPA实体来存储这个状态,我们定义了一个简单的模式来存储以下实体的状态:

ProcessDefinitionEntity
-ProcessModelEntity
ProcessInstanceEntity
-ProcessVariableEntity
TaskEntity
-TaskVarriableEntity
-TaskCandidateGroup
-TaskCandidateUser
在这里,您可以找到用于从运行时Bundle发出的事件中重新创建状态的所有事件监听器。
这些事件监听器负责理解每个特定事件,并将转换应用到现有实体或创建新的实体实例。下面的部分将解释每个侦听器的当前流。你可以提供你自己的查询服务的实现(任何其他语言),通过以下描述的行为:

ProcessDeployedEvent Handler
这个处理程序将
-创建一个新的ProcessDefinitionEntity和
--Set Cloud Metadata:
---ServiceName
---ServiceFullName
---ServiceVersion
---AppName
---AppVersion
--Set Id
--Set Description
--Set FormKey
--Set ProcessDefinitionKey
--Set Name
--Set Version
--Set Service Type
-Create a new ProcessModelEntity and
--Set ModelContent
--Set Link to ProcessDefinitionEntity
.ProcessCreatedEvent Handler
这个处理程序将:
-创建一个新的ProcessInstanceEntity和
--Set Cloud Metadata:
---ServiceName
---ServiceFullName
---ServiceVersion
---AppName
---AppVersion
--Set Id
--Set ProcessDefinitionId
--Set ProcessDefinitionKey
--Set ProcessDefinitionVersion
--Set Status to CREATED
--Set LastModified to the date inside the event
--Set Name
--Set Initiator
--Set BusinessKey
--Set StartDate
--Set ParentId
.ProcessStartedEvent Handler
这个处理程序将:
-更新现有的ProcessInstanceEntity
-检查是否有一个状态为CREATED的流程实例:
--Update the Status to RUNNING
--Set the name of the process instance
--Update LastModified
-如果没有找到流程实例,则此事件将被丢弃,并且将抛出QueryException
.ProcessUpdatedEvent Handler
这个处理程序将:
-更新现有的ProcessInstanceEntity和
--Update BusinessKey
--Update Name
--Update LastModified
-如果没有找到流程实例,则此事件将被丢弃,并且将抛出QueryException
ProcessSuspendedEvent Handler
这个处理程序将:
-更新现有的ProcessInstanceEntity和
--Update Status to SUSPENDED
--Update LastModified
-如果没有找到流程实例,则此事件将被丢弃,并且将抛出QueryException
.ProcessResumedEvent Handler
这个处理程序将:
-更新现有的ProcessInstanceEntity和
--Update Status to RUNNING
--Update LastModified
-如果没有找到流程实例,则此事件将被丢弃,并且将抛出QueryException
.ProcessCancelledEvent Handler
这个处理程序将:
-更新现有的ProcessInstanceEntity和
--Update Status to CANCELLED
--Update LastModified
-如果没有找到流程实例,则此事件将被丢弃,并且将抛出QueryException
.ProcessCompletedEvent Handler
这个处理程序将:
-更新现有的ProcessInstanceEntity和
--Update Status to COMPLETED
--Update LastModified
-如果没有找到流程实例,则此事件将被丢弃,并且将抛出QueryException
.Process & Task VariableCreatedEvent Handler
这个处理程序将:
-将检查它是否是一个任务Var

Security and Permissions

默认情况下,只有admin用户可以访问所有内容。在/admin/下的端点可以被actiti_admin角色访问。
流程实例、任务和变量数据可以限制为特定的用户或组。这可以通过添加如下属性来实现:

activiti.cloud.security.user.testuser.rb-app-name.policy.read=defKey1 
activiti.cloud.security.user.hruser.rb-app-name.policy.read=defKey2

这里的rb-app-name是运行时包应用程序的名称。或者可以使用环境变量,例如

ACTIVITI_CLOUD_SECURITY_USER_HRUSER_RBMYAPP_POLICY_READ=SimpleProcess 
ACTIVITI_CLOUD_SECURITY_GROUP_HR_RBMYAPP_POLICY_WRITE=SimpleProcess
ACTIVITI_CLOUD_SECURITY_GROUP_TESTGROUP_RBMYAPP_POLICY_WRITE=*

Implementations

https://github.com/Activiti/activiti-cloud-query/

Docker Images

https://hub.docker.com/r/activiti/activiti-cloud-query/

Activiti Cloud Audit Service

审计服务模块提供审计功能。该模块负责使用一个或多个Runtime Bundle事件,并将它们存储到事件存储中。我们的默认实现由一个简单的JPA实现组成,
它使用由Runtime bundle发出的消息,并在消息到达时存储它们。审计服务不做任何数据操作。还有一个MongoDB实现,如果您想查询以JSON格式存储的事件,它可以使您的工作更加轻松。

 

 

 Specification

Audit Service模块的核心业务逻辑可以在这里(activiti-cloud-audit-service)找到。您可以将这些实现作为Audit组件的规范,并将它们用作您自己的自定义实现的基础。
我们认识到,不同的用例可能需要在不同的环境下执行不同的技术。出于这个原因,我们提供了一个完成工作的参考实现,但在需要时我们会推荐其他方法。
如果您有兴趣为我们的参考实现提供替代方案或扩展,我们鼓励您与我们联系。

Parameters

可以使用参数来限制对REST端点的查询以匹配数据字段。例如:

/audit/v1/events?processInstanceId={processInstanceId} 
/audit/v1/events?eventType={eventType}

Security and Permissions

默认情况下,只有admin用户可以访问所有内容。可以通过将角色'user'作为actiti_admin_role环境变量的值来打开以/admin/开头的端点。
事件数据可以限制为特定的用户或角色。这可以通过添加如下属性来实现:

activiti.cloud.security.user.testuser.rb-app-name.policy.read=defKey1 
activiti.cloud.security.user.hruser.rb-app-name.policy.read=defKey2

或者可以使用通配符“*”。
这里的rb-app-name是运行时包应用程序的名称。或者可以使用环境变量,例如

ACTIVITI_CLOUD_SECURITY_USER_HRUSER_RBMYAPP_POLICY_READ=SimpleProcess 
ACTIVITI_CLOUD_SECURITY_GROUP_HR_RBMYAPP_POLICY_WRITE=SimpleProcess
ACTIVITI_CLOUD_SECURITY_GROUP_TESTGROUP_RBMYAPP_POLICY_WRITE=*

Spring Boot Starters

您可以找到Spring Boot 2。Activiti Cloud Audit services & Spring Boot starters: Activiti Cloud Audit services & Spring Boot starters:
用于在以下存储库中创建Docker映像和启用Spring Boot的服务(activiti-cloud-audit-service)

Implementations

Activiti Cloud Notification Service

为了提供可扩展的通知服务,我们评估了GraphQL和与消息传递系统(如RabbitMQ)的集成,以提供可靠的基于订阅的机制,
用户可以在其中注册由核心构建块发出的某些事件的兴趣。目前,该端点仅作为actiti_admin角色可用。

GraphQL Query Endpoint

GraphQL Query API在/ GraphQL URI上提供单条目GraphQL查询端点,支持表达过程实体模式和类型安全的查询标准表达式,
以便为使用者应用程序执行灵活、快速和声明性的数据查询。

Supported HTTP Methods, Headers, and Body

Activiti GraphQL Rest Controller同时处理HTTP GET和POST方法请求。

GET requests

当接收HTTP GET请求时,应该在查询参数中指定GraphQL查询。例如,如果我们想执行以下的GraphQL查询:

 

{
  ProcessInstance(processInstanceId:"1") {
    processInstanceId
    tasks {
      id
      name
    }
  }
}

这个请求可以通过HTTP GET像这样发送:

{
  "query": "query($id: String) { ProcessInstance(processInstanceId: $id) { processInstanceId, tasks { id, name } } }",
  "variables": { "id": "value" }
}

字段变量是可选的。
除了以上,ActivitiQraphQLController支持以下情况:
如果application/x-www-form-urlencoded Content-Type头出现在POST请求中,则应该在查询参数字符串中指定GraphQL查询。
查询变量可以在附加的查询参数variable中作为json编码的字符串发送。
如果存在"application/graphql" Content-Type头,则将HTTP POST主体内容视为graphql查询字符串。
GraphQL Query Response#
不管发送查询和变量的方法是什么,响应都会以JSON格式在请求正文中返回。

{
  "data": {
    "ProcessInstance": {
      "processInstanceId": "1",
      "tasks": [
        {
          "id": "4",
          "name": "task4",
          "assignee": "assignee",
          "status": "COMPLETED",
        },
        {
          "id": "5",
          "name": "task5",
          "assignee": "assignee",
          "status": "COMPLETED",
        }
      ]
    }
  },
  "errors": null
}

如果没有返回错误,则响应对象中的“errors”字段将为空。
GraphQL Query Schema#
Activiti GraphQL查询端点在运行时为以下实体提供从JPA实体模型派生的模式描述:ProcessInstance, Task, ProcessVariable和TaskVariable。
模式还从JPA实体模型属性派生GraphQL标量类型,以根据模式验证提供的变量值。
查询模型中的每个实体被包装到两个GraphQL查询字段中,即ProcessInstance实体在GraphQL模式中有两种表示形式:
.一种直接使用单一形式对实体建模的方法,例如通过id参数查询单个实体实例的ProcessInstance或Task。
.一种将实体包装在可分页查询请求中,并使用实体复数形式(即processinstance或Tasks)的条件表达式.
例如,如果你需要一个单一对象作为查询的根,你可以使用单一查询包装器:

query {
  ProcessInstance(processInstanceId:"1") {
    processInstanceId
    tasks {
      id
      name
      assignee
      status
    }
  }
}

将返回:

{
  "ProcessInstance": {
    "processInstanceId": "1",
    "tasks": [
      {
        "id": "4",
        "name": "task4",
        "assignee": "assignee",
        "status": "ASSIGNED"
      },
      {
        "id": "5",
        "name": "task5",
        "assignee": "assignee",
        "status": "COMPLETED"
      }
    ]
  }
}

GraphQL Pluralized Query Wrapper with Where Criteria Expressions

这个GraphtQL模式支持灵活的类型安全标准表达式,具有熟悉的SQL查询语法语义,使用where参数int select查询字段,以使用SQL查询语言提供的逻辑表达式的任何组合,
如OR, AND, EQ, NE, GT, GE, LT, LR, IN, NIN, IS_NULL, NOT_NULL, BETWEEN, NOT_BETWEEN。
例如,下面的查询将找到所有运行的带有活动任务的流程实例:

query {
  ProcessInstances(where: {
    status: { IN: RUNNING }
  }) {
    select {
      processInstanceId
      status
      tasks(where: {status: {IN: [CREATED,ASSIGNED] }}) {
        id
        name
        assignee
        status
      }
    }
  }
}

将返回

{
  "ProcessInstances": {
    "select": [
      {
        "processInstanceId": "0",
        "status": "RUNNING",
        "tasks": [
          {
            "id": "1",
            "name": "task1",
            "assignee": "assignee",
            "status": "ASSIGNED"
          }
        ]
      },
      {
        "processInstanceId": "1",
        "status": "RUNNING",
        "tasks": [
          {
            "id": "5",
            "name": "task5",
            "assignee": "assignee",
            "status": "ASSIGNED"
          }
        ]
      }
    ]
  }
}

GraphQL Reverse Query

您可以通过多对一关联中的连接对fitler结果执行反向查询。
例如:

query {
  Tasks {
    select {
      name
      assignee
      status
      processInstance(where: {processInstanceId: {EQ: "1"}}) {
        processInstanceId
        status
      }
      variables {
        name
        type
        value
      }
    }
  }
}

将返回

{
  "Tasks": {
    "select": [
      {
        "name": "task4",
        "assignee": "assignee",
        "status": "Running",
        "processInstance": {
          "processInstanceId": "1",
          "status": "RUNNING"
        },
        "variables": [
          {
            "name": "variable5",
            "type": "String",
            "value": "value5"
          },
          {
            "name": "variable6",
            "type": "String",
            "value": "value6"
          }
        ]
      },
      {
        "name": "task5",
        "assignee": "assignee",
        "status": "COMPLETED",
        "processInstance": {
          "processInstanceId": 1,
          "status": "RUNNING"
        },
        "variables": []
      }
    ]
  }
}

GraphQL Paged Queries

使用复数查询包装器和Where Criteria表达式来运行带有分页收集结果的复杂查询,并请求总记录和页面计数:

query {
  ProcessInstances(page: {start:1, limit:1}) {
    pages
    total
    select {
      processInstanceId
      tasks {
        id
        name
        assignee
        status
      }
    }
  }
}

结果将是:

{
  "ProcessInstances": {
    "pages": 2,
    "total": 2,
    "select": [
      {
        "processInstanceId": 0,
        "tasks": [
          {
            "id": "2",
            "name": "task2",
            "assignee": "assignee",
            "status": "RUNNING"
          },
          {
            "id": "3",
            "name": "task3",
            "assignee": "assignee",
            "status": "RUNNING"
          },
          {
            "id": "1",
            "name": "task1",
            "assignee": "assignee",
            "status": "COMPLETED"
          }
        ]
      }
    ]
  }
}

 

为了优化查询性能,GraphQL query DataFetcher实现将执行一个额外的查询,仅当您请求了“pages”或“total”字段时才会获得总的元素。
GraphQL Query Sorting#(GraphQL查询排序)    
对任何字段都支持排序。只需在查询字段属性中传入一个带有ASC或DESC值的'orderBy'参数。下面是Task对象按名称排序的示例。
如果没有指定排序顺序,并且没有提供默认排序顺序的字段,查询数据获取程序将使用标识字段进行默认排序,以避免分页混淆。
例如:

query {
  Tasks {
    select {
      id
      name(orderBy:DESC)
      assignee
      status
    }
  }
}

将返回

{
  "Tasks": {
    "select": [
      {
        "id": "5",
        "name": "task5",
        "assignee": "assignee",
        "status": "Completed"
      },
      {
        "id": "4",
        "name": "task4",
        "assignee": "assignee",
        "status": "Running"
      },
      {
        "id": "3",
        "name": "task3",
        "assignee": "assignee",
        "status": "Running"
      },
      {
        "id": "2",
        "name": "task2",
        "assignee": "assignee",
        "status": "Running"
      },
      {
        "id": "1",
        "name": "task1",
        "assignee": "assignee",
        "status": "Completed"
      }
    ]
  }
}

Variable Parameter Bindings
就像REST API一样,GraphQL API也可以将参数传递给端点。通过在查询定义中声明参数,自动进行类型检查。每个参数必须以$前缀命名,有一个类型。
要使用变量,只需在查询语句中的任何条件表达式中引用它。每个参数的值将在查询执行管道期间解析。

{
   "query": "query($status: String!) {
      ProcessInstances(where: {
        OR: {
          status: { EQ: $status}
        }
      }) {
        select {
          processInstanceId
          status
          tasks(where: {status: {EQ: COMPLETED}}) {
            id
            name
            assignee
            status
          }
        }
      }
    }
  ",
   "variables":{"status":"RUNNING"}
}

GraphQL Query Performance
Activiti GraphQL Data Fetcher实现将构建动态的JPA获取图,以减少对数据库执行的查询数量,以避免1+N个延迟加载问题。
How to demo Activiti GraphQL Query API#
GraphiQL应用程序浏览器可以用于简单的测试。它提供模式文档浏览器和具有自动完成支持的查询构建器,以及参数绑定。

然后,导航到http://host/notifications/graphiql加载GraphiQL浏览器。使用hradmin或testadmin用户登录。
折叠的Docs面板可以通过单击右上角的按钮打开,以公开当前的测试模式模型。
您可以在左侧面板中运行GraphQL查询。输入查询并点击运行按钮。结果应该出现在中间的面板中。如果查询有变量,则在左下角有一个最小化的面板。
只需单击它展开,并以带有引号的键的JSON字符串的形式输入变量。

GraphQL Subscription API#

Activiti Notifications GraphQL Query端点提供了一种通用机制来执行声明式查询,使用流程实例、任务和变量数据的完整且可理解的模式描述,
使用户能够以他们想要的形式确切地要求所需内容。然而,通常情况下,当用户关心的数据发生变化时,他们希望从服务器获得推送更新。为了支持这一点,
我们引入了对GraphQL订阅的支持,它通过订阅提供实时数据更新,并通过WebSockets近乎实时地推送数据通知。
How it works#
GraphQL订阅实现利用Spring的WebSocket Message Broker在客户端应用程序和后端Notification服务之间提供实时全双工通信。
GraphQL订阅类型的根提供了订阅ProcessEngineNotification类型的engineEvents查询字段:

type Subscription {
  engineEvents (
      serviceName : String, 
      appName : String, 
      processDefinitionKey : String,
      processInstanceId : String,
      businessKey : String 
  ) : ProcessEngineNotification
}

ProcessEngineNotification类型提供了数据字段来指定您可能希望作为通知有效负载的一部分接收的任何event_type的组合:

type ProcessEngineNotification {
    serviceName : String
    appName : String 
    processDefinitionKey : String 
    processInstanceId : String 
    businessKey : String 
    PROCESS_STARTED : [PROCESS_STARTED]
    PROCESS_COMPLETED : [PROCESS_COMPLETED]
    PROCESS_CREATED : [PROCESS_CREATED]
    PROCESS_CANCELLED : [PROCESS_CANCELLED]
    PROCESS_RESUMED : [PROCESS_RESUMED]
    PROCESS_SUSPENDED : [PROCESS_SUSPENDED]
    ACTIVITY_STARTED : [ACTIVITY_STARTED]
    ACTIVITY_CANCELLED : [ACTIVITY_CANCELLED]
    ACTIVITY_COMPLETED : [ACTIVITY_COMPLETED]
    VARIABLE_CREATED : [VARIABLE_CREATED]
    VARIABLE_UPDATED : [VARIABLE_UPDATED]
    VARIABLE_DELETED : [VARIABLE_DELETED]
    SEQUENCE_FLOW_TAKEN : [SEQUENCE_FLOW_TAKEN]
    TASK_CREATED : [TASK_CREATED]
    TASK_COMPLETED : [TASK_COMPLETED]
    TASK_ASSIGNED : [TASK_ASSIGNED]
    TASK_ACTIVATED : [TASK_ACTIVATED]
    TASK_SUSPENDED : [TASK_SUSPENDED]
    TASK_CANCELLED : [TASK_CANCELLED]
    INTEGRATION_REQUESTED : [INTEGRATION_REQUESTED]
    INTEGRATION_RESULT_RECEIVED : [INTEGRATION_RESULT_RECEIVED]
    TASK_CANDIDATE_USER_ADDED: [TASK_CANDIDATE_USER_ADDED]
    TASK_CANDIDATE_USER_REMOVED: [TASK_CANDIDATE_USER_REMOVED]
    TASK_CANDIDATE_GROUP_ADDED: [TASK_CANDIDATE_GROUP_ADDED]
    TASK_CANDIDATE_GROUP_REMOVED: [TASK_CANDIDATE_GROUP_REMOVED]
}

每个EVENT_TYPE都定义了自己唯一的属性,即PROCESS_STARTER事件类型定义了以下字段:

type PROCESS_STARTED {
    serviceName : String
    serviceFullName : String
    serviceVersion : String
    serviceType : String
    appName : String
    appVersion : String
    entityId : String

    id : String
    timestamp : Long
    entity : ProcessInstanceType
    eventType : String

    nestedProcessDefinitionId : String
    nestedProcessInstanceId : String    
}

它还包含ProcessInstanceType类型的内嵌实体字段,具有以下属性:

type ProcessInstanceType {
    id : String
    parentId : String
    name : String
    description : String
    processDefinitionId : String
    processDefinitionKey : String
    processDefinitionVersion : Long
    businessKey: String
    initiator : String
    startDate : String
    status : String
}
posted @ 2022-12-13 23:07  WK_BlogYard  阅读(604)  评论(0编辑  收藏  举报