Prozess-Verwaltung
Der ProcessDefinitionsClient und ProcessInstancesClient bieten umfassende Funktionen zur Verwaltung von BPMN-Prozessen und deren Instanzen.
Überblick
Die Prozess-Verwaltung umfasst folgende Hauptfunktionen:
ProcessDefinitionsClient
- Prozesse auflisten - Alle verfügbaren Prozessmodelle abrufen
- Prozess deployen - BPMN-Diagramme hochladen und deployen
- Prozess starten - Prozess-Instanzen erstellen und starten
ProcessInstancesClient
- Prozess-Instanzen abfragen - Laufende und beendete Instanzen finden
- Prozess beenden - Prozess-Instanz abbrechen
- Prozess neu starten - Fehlerhafte Prozesse wiederholen
Client erstellen
ProcessDefinitionsClient
using ProcessCube.Engine;
var engineAddress = "http://localhost:8000";
var client = ClientFactory.CreateProcessDefinitionsClient(engineAddress);ProcessInstancesClient
using ProcessCube.Engine;
var engineAddress = "http://localhost:8000";
var client = ClientFactory.CreateProcessInstancesClient(engineAddress);Schnellstart-Beispiel
Ein komplettes Beispiel vom Deployen bis zum Starten eines Prozesses:
using ProcessCube.Engine;
var engineAddress = "http://localhost:8000";
// Clients erstellen
var definitionsClient = ClientFactory.CreateProcessDefinitionsClient(engineAddress);
var instancesClient = ClientFactory.CreateProcessInstancesClient(engineAddress);
// 1. BPMN-Datei laden
var bpmnXml = await File.ReadAllTextAsync("OrderProcess.bpmn");
// 2. Prozess deployen
await definitionsClient.UploadProcessDefinitionAsync(
bpmnXml,
overwriteExisting: true
);
Console.WriteLine("Prozess erfolgreich deployed");
// 3. Prozess starten
var payload = new OrderPayload(
OrderId: "ORD-12345",
CustomerName: "Max Mustermann",
Amount: 1500.00m
);
var startResponse = await definitionsClient.StartProcessInstanceAsync(
processModelId: "OrderProcess",
startEventId: "StartEvent_1",
initialToken: payload
);
Console.WriteLine($"Prozess gestartet: {startResponse.ProcessInstanceId}");
// 4. Status prüfen
var instances = await instancesClient.QueryAsync(query => {
query.FilterByProcessInstanceId(startResponse.ProcessInstanceId);
});
var instance = instances.Single();
Console.WriteLine($"Status: {instance.State}");
// Payload-Definition
internal sealed record OrderPayload(
string OrderId,
string CustomerName,
decimal Amount
);Verwenden Sie C# Records für typisierte Prozess-Payloads. Dies ermöglicht Type Safety und IntelliSense-Unterstützung.
Prozess-Lifecycle
Ein typischer Prozess-Lifecycle mit dem .NET Client:
using ProcessCube.Engine;
using ProcessCube.Engine.ProcessInstances;
var engineAddress = "http://localhost:8000";
var definitionsClient = ClientFactory.CreateProcessDefinitionsClient(engineAddress);
var instancesClient = ClientFactory.CreateProcessInstancesClient(engineAddress);
// 1. Prozess deployen
var bpmnXml = await File.ReadAllTextAsync("ApprovalProcess.bpmn");
await definitionsClient.UploadProcessDefinitionAsync(bpmnXml, overwriteExisting: true);
// 2. Prozess starten
var startPayload = new ApprovalRequest(
RequestId: "REQ-789",
Type: "Budget",
Amount: 50000.00m,
Requestor: "alice@company.com"
);
var response = await definitionsClient.StartProcessInstanceAsync(
processModelId: "ApprovalProcess",
startEventId: "StartEvent_1",
initialToken: startPayload
);
var processInstanceId = response.ProcessInstanceId;
Console.WriteLine($"Approval-Prozess gestartet: {processInstanceId}");
// 3. Status überwachen
await MonitorProcessAsync(instancesClient, processInstanceId);
async Task MonitorProcessAsync(
IProcessInstancesClient client,
string instanceId)
{
while (true)
{
var instances = await client.QueryAsync(query => {
query.FilterByProcessInstanceId(instanceId);
});
var instance = instances.SingleOrDefault();
if (instance == null)
{
Console.WriteLine("Prozess-Instanz nicht gefunden");
break;
}
Console.WriteLine($"Status: {instance.State}");
// Prüfen ob Prozess beendet ist
if (instance.State == ProcessState.Finished)
{
Console.WriteLine("Prozess erfolgreich abgeschlossen");
break;
}
else if (instance.State == ProcessState.Error)
{
Console.WriteLine("Prozess mit Fehler beendet");
break;
}
else if (instance.State == ProcessState.Terminated)
{
Console.WriteLine("Prozess wurde abgebrochen");
break;
}
// 5 Sekunden warten
await Task.Delay(5000);
}
}
// Payload-Definition
internal sealed record ApprovalRequest(
string RequestId,
string Type,
decimal Amount,
string Requestor
);ProcessState Enum
Prozess-Instanzen können folgende States haben:
| State | Beschreibung |
|---|---|
Running | Prozess läuft aktuell |
Suspended | Prozess wartet (z.B. auf User Task) |
Finished | Prozess erfolgreich beendet |
Error | Prozess mit Fehler beendet |
Terminated | Prozess wurde manuell abgebrochen |
Best Practices
1. Typisierte Payloads verwenden
// ✅ Empfohlen - Type Safe mit Record
internal sealed record OrderPayload(
string OrderId,
string CustomerName,
decimal Amount
);
var payload = new OrderPayload("ORD-123", "Max Mustermann", 1500.00m);
await client.StartProcessInstanceAsync("OrderProcess", "StartEvent_1", payload);
// ❌ Nicht empfohlen - Anonymes Objekt
await client.StartProcessInstanceAsync(
"OrderProcess",
"StartEvent_1",
new { orderId = "ORD-123", customerName = "Max Mustermann" }
);2. Fehlerbehandlung implementieren
using ProcessCube.Engine.Client.Exceptions;
try
{
var response = await client.StartProcessInstanceAsync(
processModelId: "OrderProcess",
startEventId: "StartEvent_1",
initialToken: payload
);
}
catch (EngineClientException ex) when (ex.StatusCode == 404)
{
Console.WriteLine("Prozess wurde nicht gefunden");
}
catch (EngineClientException ex) when (ex.StatusCode == 401)
{
Console.WriteLine("Nicht authentifiziert");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Verbindungsfehler: {ex.Message}");
}3. Async/Await korrekt verwenden
// ✅ Empfohlen - Async/Await
var instances = await client.QueryAsync(query => {
query.FilterByProcessModelId("OrderProcess");
});
// ❌ Nicht empfohlen - Blockierender Call
var instances = client.QueryAsync(query => {
query.FilterByProcessModelId("OrderProcess");
}).Result; // Kann zu Deadlocks führenVerwenden Sie niemals .Result oder .Wait() auf async Tasks, da dies zu Deadlocks führen kann. Nutzen Sie immer await.
Dependency Injection
Integration in ASP.NET Core:
// Program.cs oder Startup.cs
public void ConfigureServices(IServiceCollection services)
{
var engineAddress = Configuration["ProcessCube:EngineAddress"];
// Clients als Singletons registrieren
services.AddSingleton<IProcessDefinitionsClient>(sp =>
ClientFactory.CreateProcessDefinitionsClient(engineAddress)
);
services.AddSingleton<IProcessInstancesClient>(sp =>
ClientFactory.CreateProcessInstancesClient(engineAddress)
);
}
// Controller
public class OrderController : ControllerBase
{
private readonly IProcessDefinitionsClient _definitionsClient;
private readonly IProcessInstancesClient _instancesClient;
public OrderController(
IProcessDefinitionsClient definitionsClient,
IProcessInstancesClient instancesClient)
{
_definitionsClient = definitionsClient;
_instancesClient = instancesClient;
}
[HttpPost("orders")]
public async Task<IActionResult> CreateOrder([FromBody] OrderDto order)
{
var payload = new OrderPayload(
order.OrderId,
order.CustomerName,
order.Amount
);
var response = await _definitionsClient.StartProcessInstanceAsync(
processModelId: "OrderProcess",
startEventId: "StartEvent_1",
initialToken: payload
);
return Ok(new { processInstanceId = response.ProcessInstanceId });
}
}Nächste Schritte
Erkunden Sie die einzelnen Themen:
- Prozesse auflisten - Alle Prozessmodelle abrufen
- Prozess deployen - BPMN-Diagramme hochladen
- Prozess starten - Instanzen erstellen
- Prozess-Instanzen abfragen - Laufende Prozesse finden
- Prozess beenden - Instanz abbrechen
- Prozess neu starten - Fehlerhafte Prozesse wiederholen