.NET 使用Camunda快速入门
一.工作流介绍
1. 什么是工作流
工作流(Workflow),是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。
工作流将一套大的业务逻辑分解成业务逻辑段, 并统一控制这些业务逻辑段的执行条件,执行顺序以及相互通信,实现业务逻辑的分解和解耦。
做饭:
贷款审批:
2. 为什么要使用工作流
在企业日常的管理中,经常会有出差申请、加班申请、请假申请等流程。
如果用人工的方式管理这些流程,效率低,管理成本高。
因此为了提高效率,我们需要使用到工作流开发。
3. 使用工作流有什么好处
在工作流开发中,我们可以通过每一个流程定义清楚的看到业务的所有步骤,以及每一个流程实例运行到什么位置,参与者是谁;
能够节省更多的时间成本,提升企业信息化水平。
二. 工作流引擎
1. Camunda介绍
Camunda是一种工作流引擎,是由Java开发的一个纯Java库。
工作流引擎是用来开发工作流的框架。
市面上主流的工作流引擎有Activiti、Flowable、Camunda等。
Activiti | Activiti 由 Alfresco 公司开发,目前最高版本为 Activiti cloud 7.1.0。由于团队分歧 ,在Activiti6版本衍生出了Flowable。 |
Flowable | Flowable是基于Activiti6衍生出来的版本,开发团队也是Activiti中分裂出来的,修复了Activiti6中的bug,并再此基础上实现的DMN、BPEL支持。 |
Camunda | Camunda是基于Activiti5的,最新版本是Camunda7.17,开发团队也是从Activiti中分裂出来的,发展轨迹和Flowable相似。通过压力测试验证Camunda BPMN引擎性能和稳定性更好,功能完善;除了BPMN,Camunda还支持CMMN(案例管理)和DMN(决策自动化)。Camunda不仅带有引擎,还有很多强大的工具,用于建模、任务管理、监控和用户管理等。 |
Camunda BPM(业务流程管理)平台,用来管理,部署的流程定义、执行任务、策略等等。
下载安装一个Camunda平台,成功解压 Camunda 平台的发行版后,执行名为start.bat(对于 Windows 用户)或start.sh(对于 Unix 用户)的脚本。此脚本将启动应用程序服务器。
打开您的 Web 浏览器并导航到http://localhost:8080/以访问欢迎页面,Camunda的管理平台。
Camunda Modeler(用于编辑流程图及其他模型)平台,用来定义流程图,简单说就是一个画图工具。
下载 Modeler 后,只需将下载文件解压缩到您选择的文件夹中。
成功解压缩 zip 后,运行camunda-modeler.exe(对于 Windows 用户)、camunda-modeler.app(对于 Mac 用户)或camunda-modeler.sh(对于 Linux 用户)。
2. Camunda常用Api
RepositoryService
该服务提供了管理和操控流程部署和流程定义的操作方法。
(1)查询流程引擎所知道的部署和流程定义。
(2)挂起、激活流程定义。挂起意味着不能进行下一步的操作,而激活则是反操作。
(3)获取各种资源,比如部署种包含的文件,或者引擎自动生成的流程图等。
RuntimeService
处理已经启动的流程实例,查询流程实例和执行。
TaskService
需要被用户或者系统执行的任务是流程引擎的核心,跟任务有关的资源都在这个服务中:
(1)查询分配给用户或组的任务。
(2)创建新的独立任务。
(3)控制将任务分配给那个用户,或者那些用户,以及以何种方式参与到任务中。 认领并完成一个任务。认领是指某个用户决定承担某个任务。
FormService
获取表单相关的服务,可获取启动表单、审批表单,提交表单等操作。
HistoryService
获取执行的历史任务、历史的审批记录、参数、表单等信息。
三、学习步骤:
1、Camunda 官方快速入门教程中文版: https://zhuanlan.zhihu.com/p/375908620 或者 https://blog.csdn.net/zoollcar/article/details/117351192
Camunda Rest API 文档: https://docs.camunda.org/rest/camunda-bpm-platform/7.19/
Camunda 官网: https://camunda.com/
2、使用Nuget包 Camunda.Worker GitHub 地址: https://github.com/AMalininHere/camunda-worker-dotnet 找里面的samples文件夹下的使用Demo代码
3、在VS2022上写一个Demo
3.1、创建一个.net6 web空模板服务,然后安装Nuget包 Camunda.Worker
1 |
|
3.2、Program.cs改成如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
3.3、Startup.cs 注入Camunda
using Camunda.Worker; using Camunda.Worker.Client; using CamundaDemoWeb.Handlers; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace CamundaDemoWeb { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddExternalTaskClient(client => { //client.BaseAddress = new Uri("http://localhost:8080/engine-rest"); client.BaseAddress = new Uri("http://192.168.1.153:8080/engine-rest"); }); services.AddCamundaWorker("sampleWorker") .AddHandler<SayHelloHandler>() //.AddHandler<SayHelloGuestHandler>() .ConfigurePipeline(pipeline => { pipeline.Use(next => async context => { var logger = context.ServiceProvider.GetRequiredService<ILogger<Startup>>(); logger.LogInformation("Started processing of task {Id}", context.Task.Id); await next(context); logger.LogInformation("Finished processing of task {Id}", context.Task.Id); }); }); services.AddHealthChecks(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); }); } } }
3.4、写一个SayHelloHandler
using Camunda.Worker; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace CamundaDemoWeb.Handlers { //[HandlerTopics("sayHello", LockDuration = 10_000)] //[HandlerVariables("USERNAME")] [HandlerTopics("charge-card", LockDuration = 5_000)] [HandlerVariables("amount")] public class SayHelloHandler : IExternalTaskHandler { public async Task<IExecutionResult> HandleAsync(ExternalTask externalTask, CancellationToken cancellationToken) { await Task.CompletedTask; //throw new System.NotImplementedException(); var username = externalTask.Variables["amount"].Value; //await Task.Delay(1000); return new CompleteResult { Variables = new Dictionary<string, Variable> { ["MESSAGE"] = Variable.String("Hello, Guest!") } }; } } }