Introduction
Camunda is a powerful workflow and decision automation platform. While it natively supports Java, many organizations have significant investments in .NET technologies. This guide will show you how to write a Camunda worker in C# and integrate it with a Camunda workflow. We will cover setting up the worker, configuring the workflow, and writing custom logic in C#.
Prerequisites
Before we begin, ensure you have the following:
- A running instance of Camunda (downloadable from the Camunda website).
- .NET Core SDK installed on your machine.
Step 1: Design the BPMN Workflow
First, design a BPMN model in the Camunda Modeler.
- Create a BPMN Model:
- Open Camunda Modeler and create a new BPMN diagram.
- Add a Service Task to the diagram.
- Configure the Service Task to be an external task with a specific topic.
<bpmn:serviceTask id="ServiceTask_1" name="Call C# Service" camunda:type="external" camunda:topic="csharpTopic">
<bpmn:extensionElements>
<camunda:properties>
<camunda:property name="serviceUrl" value="http://localhost:5000/api/execute"/>
</camunda:properties>
</bpmn:extensionElements>
</bpmn:serviceTask>
- Deploy the BPMN Model:
Deploy the BPMN model to the Camunda engine using the REST API or Camunda Cockpit.
Step 2: Create the C# Worker
Next, create a C# application to act as an external task worker.
- Set Up the Project:
- Create a new ASP.NET Core Web API project.
dotnet new webapi -n CamundaCSharpWorker cd CamundaCSharpWorker
- Install Dependencies:
- Install
RestSharp
for handling HTTP requests.dotnet add package RestSharp
- Implement the External Task Worker:
- Create a service in the C# application to fetch and complete tasks from Camunda.
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using RestSharp;
public class CamundaWorker : IHostedService
{
private readonly RestClient _client;
public CamundaWorker()
{
_client = new RestClient("http://localhost:8080/engine-rest");
}
public async Task StartAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var request = new RestRequest("external-task/fetchAndLock", Method.POST);
request.AddJsonBody(new
{
workerId = "csharpWorker",
maxTasks = 1,
topics = new[]
{
new { topicName = "csharpTopic", lockDuration = 10000}
}
});
var response = await _client.ExecuteAsync<ExternalTaskResponse[]>(request);
if (response.Data.Length > 0)
{
var task = response.Data[0]; Console.WriteLine($"Fetched task {task.Id}");
// Execute business logic here
var result = ExecuteBusinessLogic(task.Variables);
// Complete the task
var completeRequest =
new RestRequest($"external-task/{task.Id}/complete", Method.POST);
completeRequest.AddJsonBody(new { workerId = "csharpWorker",
variables = new { result = new { value = result } } });
await _client.ExecuteAsync(completeRequest);
Console.WriteLine($"Completed task {task.Id}");
}
await Task.Delay(5000); // Wait for 5 seconds before polling again
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
private string ExecuteBusinessLogic(dynamic variables)
{
// Custom business logic here return "result from C# logic";
}
}
public class ExternalTaskResponse
{
public string Id { get; set; }
public dynamic Variables { get; set; }
}
}
- Run the Worker:
- Ensure your application runs and is capable of fetching and completing tasks.
dotnet run
Step 3: Configuring Camunda to Use the C# Worker
- Configure Task Fetching:
Ensure your workflow is configured to use thecsharpWorker
for tasks related tocsharpTopic
. - Trigger the Workflow:
Use the Camunda REST API to start a process instance.
curl -X POST "http://localhost:8080/engine-rest/process-definition/key/yourProcessDefinitionKey/start"
- Monitor the Workflow:
Use the Camunda Cockpit to monitor workflow execution and ensure tasks are being processed by the C# application.
Custom Code Example
Here is an example of custom business logic that could be implemented in the C# worker:
private string ExecuteBusinessLogic(dynamic variables)
{
// Extract variables from the task
var input1 = variables.input1.value;
var input2 = variables.input2.value;
// Perform some computation
var result = input1 + input2;
// Return the result
return $"Computed result: {result}";
}
In this example, the worker extracts two input variables from the task, performs a simple addition, and returns the result.
Summary
Integrating a C# worker with a Camunda workflow allows you to leverage existing .NET code and infrastructure while benefiting from Camunda’s powerful workflow capabilities. By following this guide, you can set up a C# worker that communicates with Camunda via the external task pattern and REST API, enabling seamless interaction between your workflows and C# components.
This approach ensures that you can extend Camunda’s functionality with custom logic written in C#, providing a flexible and powerful solution for your workflow automation needs.