Activiti7 探索系列一构建,部署和运行自定义业务流程(一)

本文为翻译文章,如有不合理处请查看原文:https://community.alfresco.com/community/bpm/blog/2018/12/10/activiti-7-beta-building-and-deploying-a-custom-business-process

 

简介

到目前为止,在关于Activiti 7的系列文章中,我们刚刚使用了预先配置的业务流程和业务逻辑进行了开箱即用的部署。 您真正想要做的是定义自己的业务流程和业务逻辑,并将其部署到Kubernetes集群。 在本文中,我们将采用我们在上一篇文章中设计的流程定义,并将其部署为自定义Runtime Bundle。 流程定义中的服务任务将使用自定义Cloud Connector实现

我们自定义的Runtime Bundle和Cloud Connector将与我们在第一篇文章中使用的Activiti完整示例一起部署。 通过这样做,我们将看到具有不同业务流程的多个Runtime Bundl和具有不同业务逻辑的多个Cloud Connector如何与Kubernetes和Helm一起部署。

Activiti 7 Deep Dive文章系列

本文是详细介绍Activiti 7的系列文章的一部分,应按列出的顺序阅读。

  1. 部署和运行业务流程
  2. 使用Modeler设计业务流程
  3. 构建、部署和运行自定义业务流程-本文
  4. 使用核心库

前提条件

  1. 已阅读并阅读了“Activiti 7  - 使用建模器设计业务流程”文章
  2. 确保Activiti 7完整示例可以运行

源代码

您可以在此处找到与本文相关的源代码:

  • https://github.com/gravitonian/activiti7-sample-runtime-bundle
  • https://github.com/gravitonian/activiti7-sample-cloud-connector 
  • https://github.com/gravitonian/helm-repo

创建Helm存储库

我们将创建两个新服务,一个是带有流程定义的Runtime Bundle,另一个是带有服务任务实现的Cloud Connector。 他们将需要自己的部署包。 这些包需要存储在某个地方,以便其他Helm Charts能够获取它们。 例如,我们一直使用的完整示例使用其他几个Helm包来处理基础架构和建模等事情

我们想要使用完整示例设置,只需添加我们的包。 因此,我们最终会得到一个包含两个Runtime Bundle和两个Cloud Connector的完整示例。 为了做到这一点,我们的Helm Charts需要在一些Helm Repository中提供。

Helm Repository是一个HTTP服务器,它有一个index.yaml文件和所有chart 文件。 您可以使用任何HTTP服务器,但最简单的方法是使用GitHub页面。 创建一个将用于此的GitHub项目,例如(注意。您需要有一个GitHub帐户才能执行此操作):

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第1张图片

在这种情况下,我正在创建一个名为https://github.com/gravitonian/helm-repo的新GitHub项目来保存我的Helm Repository。现在,在本地克隆GitHub项目并创建一个名为gh-pages的分支:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第2张图片

下一步是将index.yaml文件添加到repo,它将包含此存储库中可用的Helm chart 包的列表:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第3张图片

GitHub仓库应该现在看起来像这样:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第4张图片

单击右侧的Settings链接并向下滚动到GitHub页面配置部分,它应如下所示:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第5张图片

我们不应该在这里改变任何东西,只是抢占网站发布的URL(即https://gravitonian.github.io/helm-repo/),这将是我们的Helm Repository URL。

在我们将这个新的Helm Repo添加到我们的本地Helm安装之前,需要上传一个chart,以便index.yaml文件看起来正确。 我们将在创建Runtime Bundle时执行此操作。

构建Runtime Bundle

Activiti 7 Runtime Bundle包含我们要执行的业务流程。Runtime Bundle执行业务流程。 它有自己的ReST API,客户可以与之对话以启动业务流程并与业务流程进行交互。 我们在这里有一个Example Runtime Bundle项目,因此使用我们的流程定义复制构建自定义Runtime Bundle以至于不会太困难

Runtime Bundle是云版本的流程引擎。 如果您将Activiti(流程引擎)作为服务公开,那么您将定义一个Runtime Bundle。 以下是有关Activiti Runtime Bundles的现状:

  1. 在Activiti 7的上下文中,Runtime Bundle表示流程引擎的无状态实例,该实例负责执行一组不可变的流程定义
  2. 无法将新流程定义部署到Runtime Bundle,因而你需要为要更新的流程定义创建一个新的不可变版本Runtime Bundle。
  3. Runtime Bundle公开ReST API是同步的和基于消息的API是异步的。
  4. Runtime Bundles使用默认的ActivitiEventListener发出事件(以fire&forget方式)(侦听内部Process Engine事件并将其转换为消息)
  5. 执行Service task(BPMN)时,Runtime Bundle将发出Integration Events,以便我们可以执行系统到系统间的集成(整合)。 Activiti Cloud Connectors将选择这些Integration Events来执行集成

下图说明:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第6张图片

Runtime Bundle可以在Spring Boot应用程序之上实现。 我们将部署Sample Runtime Bundle作为我们为测试驱动器开箱即用的完整示例的一部分。 因此,示例运行时捆绑包和我们的示例运行时捆绑包将在同一版本一起部署:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第7张图片

构建Spring Boot2.x应用程序

使用Spring Boot应用程序非常容易。 只需访问https://start.spring.io/并填写应用程序的数据,如下所示:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第8张图片

确保将Spring Boot版本2.0.x与Activiti 7 Beta 1  -  3一起使用,Beta 4应与版本2.1.x一致。你不必像我一样使用相同的Group(org.activiti.training)和Artifact(sample-activiti7-runtime-bundle)名称,只需使用你喜欢的任何内容。 但是,如果您从本文中复制代码,则使用相同的包名称(即同一组)可能会更容易。 搜索H2依赖关系,使其包含在Maven POM中。 Process Engine需要一个数据库来存储流程实例和任务实例数据。 然后单击“Generate Project”按钮。完成的Spring Boot 2 Maven项目将自动下载为ZIP。

默认Spring Boot 应用测试

在我们继续使用Activiti之前,确保Spring Boot应用程序正常工作。 这涉及两个步骤。 首先构建应用程序JAR,然后运行应用程序JAR。

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第9张图片

运行应用程序jar:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第10张图片

应用程序不包含太多内容,因此它将自行退出

依赖添加

Spring Boot应用程序具有我们需要的大多数依赖项,但Activiti 7 Runtime Bundle依赖项除外。 所以让我们添加它们。 我们可以使用BOM(物料清单)依赖关系,它将引入所有需要的Activiti 7依赖关系管理配置,包括所有依赖关系的正确版本。

将以下内容添加到pom.xml:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第11张图片

这将导入Activiti 7 Beta 3的所有依赖项管理配置。现在我们只需要添加一个Activiti 7 Runtime Bundle依赖项,该依赖项支持运行Activiti流程引擎,ReST API,事件等。将以下依赖项添加到pom.xml:

这将引入运行嵌入在Spring Boot应用程序中的Activiti 7 Runtime Bundle所需的所有Activiti和Spring依赖项。

使应用程序成为Activiti Runtime Bundle

我们现在可以使用所谓的Spring Boot Starter将此应用程序转换为Activiti 7 Runtime Bundle,将@ActivitiRuntimeBundle注释添加如SampleActiviti7RuntimeBundleApplication.java 启动类上如下图:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第12张图片

我们还不能使用这些新的依赖项运行应用程序,因为它将在resources / processes目录中查找流程定义。 如果此目录不存在,则抛出异常并停止应用程序。 但即使在抛出该异常之前,还会抛出另一个关于缺少spring.application.name属性的异常,因此我们也需要添加它。

添加Application Name属性

打开application.properties文件并添加以下属性:

在我们的案例中,sample-activiti7-rb-app名称将是默认名称。 但我们也可以通过为Docker容器设置ACT_RB_APP_NAME参数来覆盖此名称。 此属性非常重要,因为它将用于为Runtime Bundle的ReST API创建新URL,例如:{{gatewayUrl}} / sample-activiti7-rb-app / v1 / process-definitions

这应用程序名称还在微服务环境中标识此应用程序,并在向服务注册表(如Netflix Eureka服务注册表)注册时使用。 它还用于在Spring Cloud Config Server中查找 [ -  ]。[properties | yml]以及在Hashicorp的Consul或Apache Zookeeper等其他服务注册表中进行配置。

流程定义添加到应用程序

我们现在将自定义样本流程定义XML文件添加到项目中。 在src / main / resources目录下创建一个名为processes的新目录。 然后将.bpmn20.xml文件复制到此目录中。 您现在应该看到这样的目录结构:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第13张图片

测试SpringBootApp(添加了Runtime Bundle Starter和Process Definition)

我们现在可以打包并运行应用程序,以查看所有Activiti Runtime Bundle内容是否已正确加载,并且正确读取了流程定义而没有错误;(你需要跳过测试,因为它试图连接到RabbitMQ,我们只想创建App JAR)

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第14张图片

我们可以看到这一切都启动了。 我们在端口8080上启动了Apache Tomcat 8服务器以支持ReST API。 我们可以看到ReST API请求映射,例如/ admin / v1 / process-definitions。 我们现在应该可以测试它们了。 我们还可以看到正在创建的不同消息通道。 最后我们可以看到Runtime Bundle正在尝试连接到5672上的RabbitMQ消息代理,我们还没有运行它。 事实上,还有更多我们没有运行的东西,比如Keycloak,它包含用户和组。 在我们实际调用任何ReST API之前,我们需要登录Keycloak并拥有访问令牌。

测试新运行时捆绑包的最佳方法是使用它创建Docker镜像,然后将其部署到我们刚刚在上一节中测试的现有群集。 但在我们开始创建一个新的Docker Image之前,我们还需要配置一些东西。

配置App以使用Keycloak进行身份验证

部署的所有Runtime Bundles都使用Keycloak进行用户身份验证。 所以我们需要告诉我们的Runtime Bundle它可以在哪里找到Keycloak服务器。

打开项目的application.properties配置文件并添加以下属性:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第15张图片

当应用程序通过ACT_ *属性替换初始化时,几乎所有这些属性都可以设置其值。

配置应用程序以生成和使用异步消息

部署的所有运行时捆绑包都使用Spring Cloud Stream来生成和使用异步消息。 这些消息可以来自例如RabbitMQ,Runtime Bundle使用Spring AMQP协议来实现RabbitMQ。 我们需要告诉我们的Runtime Bundle不同的消息目的地是什么。

打开项目的application.properties配置文件并添加以下属性:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第16张图片

通过ACT_ *属性替换初始化应用程序时,所有这些属性都可以设置其值。

配置应用程序以连接到Zipkin以进行跟踪

部署的所有Runtime Bundle都使用Zipkin,它是一个分布式跟踪系统。 它有助于收集解决微服务架构中的延迟问题所需的时序数据。 它管理这些数据的收集和查找。

打开项目的application.properties配置文件并添加以下属性:

其他应用程序配置

我们还需要提供一些配置属性,打开项目的application.properties配置文件并添加以下属性:

部署Runtime Bundle

在本节中,我们将介绍部署Runtime Bundles的一种方法。

构建Runtime Bundle的docker镜像

我们现在使用自定义流程定义完成了Runtime Bundle。 为了使用它,我们需要将它作为可用Docker镜像。 为了生成Docker镜像,我们需要一个Dockerfile。 使用以下内容在项目的顶级目录中创建一个Dockerfile文件:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第17张图片

这将创建基于Alpine linux和OpenJDK的Runtime Bundle图像。 我们需要运行它。将它在端口8080暴露。

让我们的Maven项目在Fabric8 Maven插件的帮助下自动为我们构建镜像。 将它添加到sample-activiti7-runtime-bundle / pom.xml中,如下所示:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第18张图片

现在,为了构建Docker镜像,我们只需要执行以下maven命令:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第19张图片

确保我们得到镜像通过查看本地镜像列表:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第20张图片

我们现在准备好了在Activiti 7部署的Runtime Bundle镜像

部署自定义Runtime Bundle镜像

我们现在要做的是将Runtime Bundle与必要的服务和基础架构一起部署。 我们可以使用先前的完整示例Helm Chart设置。 我们只需要将我们Sample Runtime Bundle添加到此解决方案部署中。 为此,我们需要为Runtime Bundle创建一个Helm包。

Sample Runtime Bundle创建Helm Charts

最简单的方法是将开箱即用的示例Runtime Bundle的Helm Charts复制到我们的Helm Repo项目(我们之前创建的GitHub页面项目,在我的案例中为https://github.com/gravitonian/helm-repo):

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第21张图片

现在我们可以更新这些Charts以匹配我们的Sample Runtime Bundle。

打开helm-repo / charts / sample-runtime-bundle / Chart.yaml文件并将其更新为如下所示,更改名称和版本(注意。Chart的名称及其包含的目录必须匹配):

接下来打开helm-repo / charts / sample-runtime-bundle / requirements.yaml文件并删除其所有内容,我们不会使用PostgreSQL。然后打开helm-repo / charts / sample-runtime-bundle / values.yaml文件并将其更新为如下所示:

# Default values for Maven projects.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
global:
 rabbitmq:
 host:
 value: ""
 username:
 value: guest
 password:
 value: guest
 keycloak:
 url: ""
 name: keycloak
 service:
 type: http
 port: 80
 ## The list of hostnames to be covered with this ingress record.
 ## Most likely this will be just one host, but in the event more hosts are needed, this is an array
 ingress:
 hostName: ""
db:
 uri: ""
 name: activitipostgresql
 deployPostgres: false
 port: 5432

activitipostgresql:
 postgresPassword: activiti

## Allows the specification of additional environment variables
extraEnv: |
 # - name: ACT_KEYCLOAK_URL
 # valueFrom:
 # configMapKeyRef:
 # name: {{ .Release.Name }}-keycloak-http
 # key: expose-keycloak-service-key

javaOpts:
 xmx: 768m
 xms: 512m
 other: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true -XX:+UseParallelGC -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90
image:
 repository: activiti-runtime-bundle-custom
 tag: 0.0.1-SNAPSHOT
 pullPolicy: IfNotPresent
service:
 name: sample-activiti7-rb-app
 type: ClusterIP
 externalPort: 80
 internalPort: 8080
 annotations:
 fabric8.io/expose: "false"
resources:
 limits:
 memory: 768Mi
 requests:
 cpu: 400m
 memory: 768Mi
probePath: /actuator/health
livenessProbe:
 initialDelaySeconds: 140
 periodSeconds: 15
 successThreshold: 1
 timeoutSeconds: 4
readinessProbe:
 periodSeconds: 15
 successThreshold: 1
 timeoutSeconds: 3
terminationGracePeriodSeconds: 20


ingress:
 ## Set to true to enable ingress record generation
 enabled: false

 path: /rb-sample-app

 ## Set this to true in order to enable TLS on the ingress record
 tls: false

 ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS
 tlsSecret: myTlsSecret

 ## Ingress annotations done as key:value pairs
 annotations:
 kubernetes.io/ingress.class: nginx
 nginx.ingress.kubernetes.io/rewrite-target: /
 nginx.ingress.kubernetes.io/enable-cors: "true"
 nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Port, X-Forwarded-Prefix,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-CSRF-Token,Access-Control-Request-Headers,Access-Control-Request-Method,accept,Keep-Alive"
 nginx.ingress.kubernetes.io/x-forwarded-prefix: "true"

以下值请更新:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第22张图片

打包并发布Sample Runtime Bundle的Helm Chart

我们现在准备为Sample Runtime Bundle Helm Chart创建一个Helm包。在/ helm-repo目录中执行以下命令:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第23张图片

现在,让我们将包括包的所有chart 文件上传到我们的Helm Repository(即https://github.com/gravitonian/helm-repo)。 首先生成索引文件:

此命令生成index.yaml文件。 我们来看看它

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第24张图片

helm repo GitHub项目现在看起来像这样:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第25张图片

提交并推送更改

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第26张图片

添加我们的Helm Repository初始化本地Helm

我们现在可以将此Helm repo添加到我们的Helm安装中,如下所示:

更新仓库以确保我们在本地获得所有最新资料:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第27张图片

更新完整实例以部署Sample Runtime Bundle

在activiti-cloud-charts / activiti-cloud-full-example / requirements.yaml文件中添加对Sample Runtime Bundle的依赖:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第28张图片

对于要获取的Sample Runtime Bundle的新依赖项,我们需要更新依赖项,如下所示:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第29张图片

你应该看到包含下载的依赖项的charts目录:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第30张图片

通过完整实例Helm Charts部署Sample Runtime Bundle

我们现在准备使用 sample runtime bundle升级我们正在运行的完整示例解决方案(假设它以前正在运行)。 首先检查完整示例部署的名称:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第31张图片

我们可以看到完整示例部署的名称为cloying-possum。 执行以下Helm命令进行升级:

请注意,我们不能像在使用activiti-cloud-charts / activiti-cloud-full-example安装之前那样参考Activiti Helm Repo中的完整示例 helm chart 包。 这是因为我们改变的不仅仅是values.yaml。 我们也在改变requirements.yaml(即依赖项)。 并且远程activiti-cloud-charts / activiti-cloud-full-example helm包中的依赖关系仍然是相同的,因此我们需要从本地目录中只用点(.)获取chart信息。

查看Kubernetes仪表板并确保正确部署新的Runtime Bundle:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第32张图片

在继续之前,让我们确保我们可以在新的Sample Runtime Bundle中调用ReST API。 在Postman中复制rb-my-app集合,以便我们可以更新其中的URL。 然后将getProcessDefintions调用的URL从{{gatewayUrl}} / rb-my-app / v1 / process-definitions更新为{{gatewayUrl}} / sample-activiti7-rb-app / v1 / process-definitions。 所以调用的目标是新的Sample Runtime Bundle。

现在进行getKeycloakToken调用以获取身份验证令牌。 然后在新更新的集合中进行getProcessDefinitions调用:

Activiti7 探索系列一构建,部署和运行自定义业务流程(一)_第33张图片

一切似乎都很好。 但是,在我们运行新流程定义之前,我们需要为Service Task 1实现自定义云连接器。

 

未完待续!!!点我继续

 

你可能感兴趣的:(activiti,cloud,Activit7,Activiti,cloud)