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.

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

  1. Set Up the Project:
  • Create a new ASP.NET Core Web API project. dotnet new webapi -n CamundaCSharpWorker cd CamundaCSharpWorker
  1. Install Dependencies:
  • Install RestSharp for handling HTTP requests. dotnet add package RestSharp
  1. Implement the External Task Worker:
  2. 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; }
        }
}
  1. 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

  1. Configure Task Fetching:
    Ensure your workflow is configured to use the csharpWorker for tasks related to csharpTopic.
  2. 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"
  1. 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.

How to Write a Camunda Worker in C# and Use It in a Camunda Workflow

Johannes Rest


.NET Architekt und Entwickler


Beitragsnavigation


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert