Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

The system-level architecture: the plane split, route lifecycle, shutdown and backpressure, and the crate dependency graph. The Core concepts section holds the mental model. This page builds on it and indexes the decisions that shaped it.

Data plane vs control plane

rust-camel separates message flow from lifecycle. The data plane is the hot path. Every Exchange flows through a Tower Service<Exchange> pipeline. The control plane is the cold path. It owns route lifecycle through a CQRS RuntimeBus with optimistic versioning.

The Data plane vs control plane concept page covers the rationale, the performance and safety goals, and the Exchange trust boundary. ADR-0001 records the decision to adopt Tower as the data-plane foundation.

Route lifecycle

Route lifecycle follows a two-phase persist-then-execute pattern (ADR-0018). The Runtime records intent before side effects, then confirms or compensates after the side effect returns. For StartRoute, the sequence is:

  1. Record RouteStartRequested, project Route as Starting
  2. Start the Consumer and Pipeline
  3. Record RouteStarted, project Started

If the side effect fails after intent was recorded, the Runtime records RouteFailed, projects Failed, and publishes failure events. Compensation applies to every non-atomic lifecycle flow (ADR-0018).

The lifecycle layer uses hexagonal architecture (ADR-0003). Domain and application logic sit behind ports (RouteRepositoryPort, ProjectionStorePort, RuntimeEventJournalPort, RuntimeExecutionPort). Concrete adapters provide in-memory and redb implementations. ADR-0045 extends this discipline crate-wide. Every behavioral area in camel-core is a vertical slice with its own domain / application / ports / adapters layout.

Stateful pipeline steps (aggregators, resequencers, idempotent repositories) implement the StepLifecycle trait (ADR-0022). The trait adds a drain hook that outlives a single process() call. The drain lets background work (timers, buckets, queues) complete before the step shuts down.

Shutdown and backpressure

A route stop signals in-flight pipelines through a tokio::task_local! cancel token (ADR-0043). The step loop checks the token before each step and returns Failed(ConsumerStopping) on cancel. This gives cooperative cancellation without interrupting a step mid-.await. The Data plane vs control plane page covers the token mechanics and the graceful-drain ordering.

Route-admission backpressure (ADR-0044) caps concurrent in-flight Exchanges. The Concurrent consumer model acquires a semaphore permit before it dequeues work. When permits run out, the consumer blocks on the permit instead of buffering more work inside the pipeline task. This bounds memory under load.

Crate dependency overview

The crate dependency graph follows a layered structure. Contract crates sit at the bottom with zero or minimal internal dependencies. Runtime and processing crates depend on contracts. Components, languages, and services depend on the runtime and contracts. Platforms depend on services.

Platforms
    |
Services
    |
Components ----> Runtime ----> Processors
    |               |              |
    |               v              v
    +---------> Contracts <--------+
                    ^
                    |
              Languages

Contracts (camel-api, camel-component-api, camel-language-api, camel-wit, camel-config, camel-endpoint, camel-bean, camel-test, camel-bench) define the types and traits that every other crate depends on. They have no runtime dependency.

Runtime (camel-core, camel-cli, camel-health) owns the execution engine, route lifecycle, hot reload, and registries. camel-core depends on contract crates and drives every other family.

Processors (camel-processor, camel-builder) implement EIP patterns as Tower middleware. They depend on camel-api for Exchange and Processor.

DSL (camel-dsl) parses YAML and JSON route definitions into RouteDefinition. It depends on camel-api and camel-builder.

Components connect routes to external systems. Each component crate depends on camel-component-api and camel-core. See the component catalog for the full list.

Languages evaluate expressions and predicates. Each language crate depends on camel-language-api. See the language catalog for the full list.

Services provide cross-cutting infrastructure: auth, observability, and function invocation. They register into CamelContext through the service contracts. See the service catalog for the full list.

Platforms expose deployment-aware behaviour. See the platform catalog for the full list.

Data formats convert between wire representations and structured body types. See the data format catalog for the full list.

For the complete bounded-context map and domain vocabulary, see CONTEXT-MAP.md.

ADR index

Architecture-shaping choices live as ADRs under ../adr/. The index below organizes them by topic. Each entry links to the ADR file and gives a one-sentence summary.

See also Important Findings Summary for resolved P0 findings.

Architecture and Design

Core patterns, lifecycle, pipeline, and route authoring.

ADRTitleSummary
0001Tower data plane, custom-trait control planeSeparates Exchange processing (Tower Service<Exchange>) from component lifecycle (custom traits).
0002CQRS RuntimeBus for route lifecycleRoute lifecycle mutations go through RuntimeCommandBus with projections and optional event journal.
0003Hexagonal lifecycle coreLifecycle layer uses ports and adapters for persistence and testability.
0004Hot reload via atomic pipeline swapPipeline swap uses ArcSwap so in-flight Exchanges complete against the snapshot they entered.
0005Function out-of-process staged reloadfunction: steps run in isolated containers with prepare/finalize/discard registration.
0006Script synchronous, async to functionJavaScript evaluation is synchronous; async paths delegate to function:.
0007Route-supervised consumer failureConsumer task failure is route-supervised with optional restart policy and backoff.
0008Route templates via JSON tree substitutionTemplate placeholders expand via JSON tree walk before DSL deserialization.
0009HTTP co-hosting API and static routesAPI routes and static mounts share one server per host/port with deterministic dispatch.
0011CanonicalRouteSpec minimal contractv1 is a stable minimal route contract, not a full RouteDefinition mirror.
0015Endpoint-created PollingConsumerPull-based adapter created from an Endpoint for pollEnrich and WASM camel_poll.
0016CanonicalRouteSpec v2 contractv2 adds lifecycle metadata with strict rejection for unsupported fields.
0017DSL YAML snake_case namingDSL keys use snake_case to match Rust field names and schema output.
0018Two-phase route lifecycle persistenceLifecycle commands persist intent before side effects, compensate on failure.
0022StepLifecycle trait and drainStateful pipeline steps get a separate drain hook for background work.
0024PipelineOutcome replaces CamelError::StoppedPipelineOutcome enum replaces CamelError::Stopped for pipeline control flow.
0025Outcome-aware structural EIPsStructural EIPs return PipelineOutcome directly instead of Tower Result.
0026JSON canonical route authoringJSON is the canonical full-DSL format for SDKs and generators; YAML is human convenience.
0029Resequencer continuation boundaryCompiler splits step list at Resequence; post-steps compile into a continuation owned by the service.
0030Exchange-aware DataFormat hooksDataFormat gains default marshal_in_exchange / unmarshal_in_exchange hooks.
0031WASM source worldFourth WIT world source lets WASM guests act as Consumers with their own consumption loop.
0041Component metadata capabilities schemaComponentMetadata schema with OptionKind, UriOption, ComponentCapabilities, CapabilityQuery.
0042Arc<[CompiledStep]> shared snapshotShared snapshot avoids per-Exchange Vec clone for compiled pipeline steps.
0043Pipeline cancellation between stepstask_local! cancel token checked between steps for cooperative cancellation.
0044Route-admission backpressureSemaphore permit acquired before dequeue prevents unbounded in-flight work.
0045camel-core architecture charterCodifies Clean + DDD + CQRS + vertical slices + hexagonal discipline crate-wide.
0046Apache Camel inspiration, not conformanceApache Camel is design inspiration, not conformance authority.
0047Template rendering engineMiniJinja-based external template engine with compile-once caching and atomic hot reload.
0053WIT interface versioningcamel:plugin uses one package-level WIT SemVer, independent from Rust crate versions.

Security

Authentication, authorization, trust boundaries, and capability models.

ADRTitleSummary
0010SecurityPolicy pre-pipeline authorizationRoute-level authorization wraps the Pipeline before any step runs.
0032Exchange-data trust boundaryOperator config is trusted; exchange data is untrusted and must not drive control-plane actions.
0033Security defaults and fail-closed startup validationFive-disposition security policy enforced by a single startup-validation phase.
0034ControlBus capability authorizationControlBus requires an authorizedRoutes allowlist and denies self-restart.
0035Leader-epoch fencing tokenEvery master: delegate envelope carries a monotonic fencing token for split-brain safety.
0036Bridge IPC mutual TLSBridge uses mutual TLS with ephemeral certificates; fail-closed guard rejects placeholder paths.
0037Exec component fail-closed capability modelAllowlisted binaries, argument policy, no shell, bounded stdin.
0050WASM sandbox capability posturePer-world grants for Camel host functions and selective WASI registration.
0051Credential redaction at diagnostic boundariesCredential-bearing types use manual redacting Debug; Serialize must not expose credential bytes.
0052Diagnostic endpoint exposure postureDiagnostic endpoints follow the Prometheus scrape model; network isolation is the operator's duty.

Error Handling

Disposition, drain, supervision, and repository patterns.

ADRTitleSummary
0012Log-level convention by handler-contract boundariesEmitters inside a handler contract log at warn! or below; outside emitters may log at error!.
0019Error disposition in-pipeline recoveryRouteErrorHandler trait injected into the pipeline decides disposition after each step failure.
0023Idempotent Repository traitKey-only IdempotentRepository trait in camel-api for duplicate detection.
0028Claim Check Repository traitPayload-bearing ClaimCheckRepository trait distinct from key-only IdempotentRepository.

Performance and Limits

DoS caps, cardinality limits, and resource bounds.

ADRTitleSummary
0038Configurable DoS capsPer-format config channel for operator-overridable data-format DoS caps.
0039Configurable loop iteration capPer-step max_iterations escape hatch for loop iteration limits.
0040Configurable materialize limitsConfigurable materialize limits for XSLT, XJ, and WASM producers.

Integration

WASM, functions, components, and cross-cutting contracts.

ADRTitleSummary
0013NetworkRetryPolicy and migrationCentralized retry semantics and migration boundaries for adapter retries.
0014WASM plugin config unificationUnified WASM plugin runtime configuration across all plugin types.
0020LLM component provider adapter boundaryLLM component isolates SDK behind a project-owned LlmProvider trait.
0021LLM retry with retry-after manual loopLLM retry honors provider retry_after via manual loop, diverging from ADR-0013.
0027MQTT component 3.1.1 per-endpointMQTT 3.1.1 via rumqttc with one connection per Consumer or Producer.
0048Attestation provenance (retired)Retired HMAC-SHA256 attestation decision kept for history.
0049Workspace non-exhaustive policyPublic contract enums are #[non_exhaustive] by default before the 1.0 API freeze.