back to All projects

Professional

Camunda Sink

Overview

Camunda Sink connected event-driven business systems with Camunda workflows. It consumed configured events from the company messaging platform, transformed them into Camunda-specific integration patterns, and handled correlation, retries, timeouts, tenant rules and failed-event reprocessing. I contributed extensively to its architecture and evolution, including project restructuring, dynamic configuration, handler registration, multi-tenant behavior, back-office tooling, asynchronous global-message processing, reliability improvements and platform modernization.

My Role

  • Restructured the service into separate API, application, consumer, data and worker projects and introduced a Web API surface for operational configuration.
  • Implemented Azure Blob Storage-backed event configuration with automatic polling and reload-on-change behavior, allowing event routing changes without redeploying the service.
  • Built dynamic event handler registration and a handler factory capable of routing configured event types to correlation-message, signal or global-message processing.
  • Extended the Camunda integration with asynchronous global-message processing that updates variables across subscribed process instances and monitors Camunda batch completion.
  • Implemented tenant-aware event processing and configurable tenant suppression, including API, back-office and audit behavior.
  • Improved reliability through differentiated Polly retry policies, timeout handling, circuit-breaker behavior and safer failed-event storage and reprocessing.
  • Built a Blazor back-office application and generated API client for inspecting and managing handled-event configuration.
  • Implemented a maintenance service for cleaning expired Dead Events Storage records and associated blobs, including Azurite-backed integration tests and CI/CD support.
  • Migrated the multi-project service and deployment tooling to .NET 7.

Architecture & Technology

  • .NET worker services consuming business events and commands through Ori.Messaging over Azure Service Bus
  • ASP.NET Core Web API for viewing and updating handled-event configuration
  • Dynamic event handler factory supporting Camunda correlation messages, signals and global variable updates
  • Camunda OpenAPI client integration for message correlation, signal delivery and asynchronous process-variable batch updates
  • Azure Blob Storage-backed runtime configuration with ETag-based reload detection and IOptionsMonitor change propagation
  • Azure Table Storage, Blob Storage and Queue Storage for failed-event persistence and reprocessing
  • Polly retry and circuit-breaker policies with integration-specific timeout and retry behavior
  • Server-side Blazor back-office UI with generated API client
  • Application Insights telemetry, audit logging, Docker and Azure DevOps CI/CD

Engineering Challenges

  • Route many event types into different Camunda integration patterns while keeping behavior configurable and avoiding large amounts of event-specific infrastructure code.
  • Apply configuration changes at runtime without redeploying the service or leaving consumers registered with stale handler definitions.
  • Handle Camunda operations with very different execution characteristics, from synchronous correlation messages to long-running signals and asynchronous batch updates.
  • Avoid unsafe retries for operations where Camunda could still be processing a timed-out request and retrying could create duplicate side effects.
  • Support multi-tenant event processing while allowing selected tenants to be suppressed dynamically at configuration level.
  • Preserve failed-event data for investigation and reprocessing while safely managing the lifecycle of metadata and associated blob payloads.

Decisions & Trade-offs

  • Model event handling as configurable handler types rather than implementing separate hard-coded pipelines for every event. A handler factory resolved event and handler type into correlation-message, signal or global-message processing.
  • Store handled-event configuration in Azure Blob Storage and monitor ETags for changes. This enabled operational routing changes without rebuilding or redeploying the service.
  • Restart and re-register event consumers when configuration changed instead of attempting to mutate active handler registrations in place. This kept runtime behavior aligned with the latest configuration.
  • Treat long-running Camunda signals and global-message operations differently from standard correlation messages. Some timeout scenarios were deliberately moved to Dead Events Storage rather than retried automatically to reduce the risk of duplicate Camunda-side work.
  • Run global-message delivery asynchronously and monitor Camunda batch completion because updating multiple subscribed process instances could outlive the normal message-handler execution window.
  • Keep failed-event cleanup as a separate maintenance process and delete blob payloads only after the corresponding storage metadata had been removed successfully, reducing the risk of inconsistent cleanup.

Results & Impact

  • Enabled configuration-driven routing of business events into multiple Camunda integration patterns.
  • Allowed handled-event configuration to be changed at runtime through Blob Storage-backed configuration and dynamic consumer re-registration.
  • Extended the integration beyond direct message correlation to tenant-aware signals and asynchronous process-variable updates.
  • Improved production reliability with tailored retry, timeout and failed-event handling for different Camunda operations.
  • Provided internal operational tooling for inspecting and managing event configuration through a Web API and Blazor back office.
  • Added lifecycle management for failed-event storage through a dedicated maintenance service with integration-test coverage.
  • Modernized the service architecture and runtime through project restructuring and migration to .NET 7.