zb-client-accelerator
0.8.1
See the version list below for details.
dotnet add package zb-client-accelerator --version 0.8.1
NuGet\Install-Package zb-client-accelerator -Version 0.8.1
<PackageReference Include="zb-client-accelerator" Version="0.8.1" />
paket add zb-client-accelerator --version 0.8.1
#r "nuget: zb-client-accelerator, 0.8.1"
// Install zb-client-accelerator as a Cake Addin #addin nuget:?package=zb-client-accelerator&version=0.8.1 // Install zb-client-accelerator as a Cake Tool #tool nuget:?package=zb-client-accelerator&version=0.8.1
Bootstrap Accelerator for the C# Zeebe client
This project is an extension of the C# Zeebe client project. Zeebe Job handlers are automaticly recognized and bootstrapped via a .Net HostedService.
Read the Zeebe documentation for more information about the Zeebe project.
The basic idea and implementation for this came from https://github.com/camunda-community-hub/zeebe-client-csharp-bootstrap. We loved the idea, but had in some parts our own preferences for defaults and behaviour. So this is our version of a good Bootstrap Extension for the C# Zeebe Client. Credits for the base work still belong to https://github.com/arjangeertsema.
Requirements
- net standard 2.0 or higher, which means
- .net core 2.1 or higher
- or .net framework 4.7.1 or higher
- latest C# Zeebe client release
- latest Zeebe release
How to use
The Zeebe C# client bootstrap extension is available via nuget (https://www.nuget.org/packages/zb-client-accelerator/).
Quick start
All classes which implement IJobHandler<ZeebeJob>
, IJobHandler<ZeebeJob, TResponse>
, IAsyncJobHandler<ZeebeJob>
or IAsyncJobHandler<ZeebeJob, TResponse>
are automatically found, added to the service collection and autowired to Zeebe when you register this bootstrap project with the IServiceCollection.BootstrapZeebe()
extension method.
More power is provided by using global::Zeebe.Client.Accelerator.Extensions;
which provides you with further extensions for IHost
, IZeebeClient
etc. in
order to deploy processes or create one time message receivers.
Bootstrap Zeebe
The BootstrapZeebe
method has two parameters:
ZeebeBootstrapOptions
via configuration, action delegate or both.- An array with assemblies which will be scanned for job handlers.
ConfigureServices((hostContext, services) => {
services.BootstrapZeebe(
hostContext.Configuration.GetSection("ZeebeConfiguration"),
this.GetType().Assembly
);
})
Example Web Application:
// Start building my WebApplication
var builder = WebApplication.CreateBuilder(args);
// Bootstrap Zeebe Integration
builder.Services.BootstrapZeebe(
builder.Configuration.GetSection("ZeebeConfiguration"),
typeof(Program).Assembly);
The configuration will e.g. look as follows:
{
"ZeebeConfiguration": {
"Client": {
"GatewayAddress": "127.0.0.1:26500"
},
"Worker": {
"MaxJobsActive": 5,
"TimeoutInMilliseconds": 500,
"PollIntervalInMilliseconds": 50,
"PollingTimeoutInMilliseconds": 1000,
"RetryTimeoutInMilliseconds": 1000
}
},
...
}
If we want to deploy some processes right before the final startup of our application we create a deployment using the extension for IHost
or IServiceProvider
as follows:
var app = builder.Build();
...
// Deploy all process resources
app.CreateZeebeDeployment()
.UsingDirectory("Resources")
.AddResource("insurance_application.bpmn")
.AddResource("document_request.bpmn")
.AddResource("risk_check.dmn")
.Deploy();
// Now run the application
app.Run();
Job Handler
The job handler is an implementation of IJobHandler<ZeebeJob>
, IJobHandler<ZeebeJob, TResponse>
, IAsyncJobHandler<ZeebeJob>
or IAsyncJobHandler<ZeebeJob, TResponse>
. Job handlers are automaticly added to the DI container, therefore you can use dependency injection inside the job handlers. The default job handler configuration can be overwritten with AbstractJobHandlerAttribute
implementations, see attributes for more information.
[JobType("doSomeWork")]
public class SimpleJobHandler : IAsyncJobHandler<ZeebeJob>
{
private readonly MyApiService _myApiService;
public SimpleJobHandler(MyApiService myApiService)
{
_myApiService = myApiService;
}
public async Task HandleJob(ZeebeJob job, CancellationToken cancellationToken)
{
// execute business service etc.
await _myApiService.DoSomethingAsync(cancellationToken);
}
}
Of course you are able to access process variables and return a result. E.g.:
[JobType("doAwesomeWork")]
public class SimpleJobHandler : IAsyncJobHandler<ZeebeJob<SimpleJobPayload>, SimpleResponse>
{
private readonly MyApiService _myApiService;
public SimpleJobHandler(MyApiService myApiService)
{
_myApiService = myApiService;
}
public async Task<SimpleResponse> HandleJob(ZeebeJob<SimpleJobPayload> job, CancellationToken cancellationToken)
{
// get variables as declared (SimpleJobPayload)
var variables = job.getVariables();
// execute business service etc.
var result = await _myApiService.DoSomethingAsync(variables.CustomerNo, cancellationToken);
return new SimpleResponse(result);
}
class SimpleJobPayload
{
public string CustomerNo { get; set; }
}
}
And there are more options, including the option to access custom headers configured in the process model:
[JobType("doComplexWork")]
public class SimpleJobHandler : IAsyncJobHandler<ZeebeJob>
{
private readonly MyApiService _myApiService;
public SimpleJobHandler(MyApiService myApiService)
{
_myApiService = myApiService;
}
public async Task HandleJob(ZeebeJob job, CancellationToken cancellationToken)
{
// get all variables (and deserialize to a given type)
ProcessVariables variables = job.getVariables<ProcessVariables>();
// get custom headers
MyCustomHeaders headers = job.getCustomHeaders<MyCustomHeaders>();
// execute business service etc.
await _myApiService.DoSomethingComplex(variables.Customer, headers.SomeConfiguration, cancellationToken);
...
}
class ProcessVariables
{
public string? BusinessKey { get; set; }
public CustomerData Customer { get; set; }
public string? AccountName { get; set; }
...
}
class MyCustomHeaders
{
public string SomeConfiguration { get; set; }
}
}
If you like to explicitely restrict the variables fetched from Zeebe, you have the following additional option:
[JobType("doComplexWork")]
[FetchVariables("businessKey", "applicantName")]
public class SimpleJobHandler : IAsyncJobHandler<ZeebeJob>
{
...
}
A handled job has three outcomes:
- The job has been handled without exceptions: this will automaticly result in a
JobCompletedCommand
beeing send to the broker. The optionalTResponse
is automaticly serialized and added to theJobCompletedCommand
. - A
BpmnErrorException
has been thrown while handling the job: this will automaticly result in aThrowErrorCommand
beeing send to the broker triggering Error Boundary Events in the process. - Any other unexpected exception will automatically result in a
FailCommand
beeing send to the broker including message details and reducing the number of retries;
Dynamic message receiver
See Example for synchronous responses from processes for a description of the scenario.
You can create a one time job handler for receiving a message for a dynamic job type "received_" + number
as follows:
try
{
string jsonContent = _zeebeClient.ReceiveMessage("received_" + number, TimeSpan.FromSeconds(5), "someVariable1", "someVariable2");
...
} catch (MessageTimeoutException)
{
// nothing received
...
}
Simply waiting without receiving any variables:
bool messageReceived = _zeebeClient.ReceiveMessage("received_" + number, TimeSpan.FromSeconds(3));
The one time job handler will be destroyed after ReceiveMessage
returns.
Hints
- By default the job handlers are added to de DI container with a
Transient
service lifetime. This can be overriden by adding theServiceLifetimeAttribute
to the job handler, see attributes for more information. - By default the
ZeebeVariablesSerializer
is registered as the implementation forIZeebeVariablesSerializer
which usesSystem.Text.Json.JsonSerializer
. Serialization / Deserialization uses CamelCase as naming policy. - The default job type of a job handler is the class name of the job handler. This can be overriden by adding the
JobTypeAttribute
to the job handler, e.g.[JobType("myJobName")]
.
How to build
Run dotnet build Zeebe.Client.Bootstrap.sln
How to test
Run dotnet test Zeebe.Client.Bootstrap.sln
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Configuration.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Hosting (>= 7.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 7.0.0)
- zb-client (>= 1.2.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.1.11 | 5,882 | 9/30/2024 |
2.1.10 | 5,688 | 7/31/2024 |
2.1.9 | 538 | 7/17/2024 |
2.1.8 | 2,097 | 5/24/2024 |
2.1.7 | 1,427 | 3/27/2024 |
2.1.6 | 321 | 3/15/2024 |
2.1.5 | 2,321 | 3/4/2024 |
2.1.4 | 4,835 | 12/20/2023 |
2.1.3 | 6,035 | 10/16/2023 |
2.1.2 | 547 | 10/15/2023 |
2.1.1 | 492 | 10/15/2023 |
2.1.0 | 498 | 10/15/2023 |
2.0.0 | 613 | 8/18/2023 |
1.1.0 | 595 | 8/18/2023 |
1.0.4 | 3,656 | 5/31/2023 |
1.0.3 | 931 | 5/25/2023 |
1.0.2 | 1,883 | 4/6/2023 |
1.0.1 | 981 | 3/17/2023 |
1.0.0 | 787 | 3/1/2023 |
0.8.5 | 831 | 12/15/2022 |
0.8.4 | 797 | 12/9/2022 |
0.8.3 | 741 | 12/1/2022 |
0.8.2 | 834 | 11/29/2022 |
0.8.1 | 861 | 11/29/2022 |