zerodds-routing-service

In-DDS routing service. Forwards samples between DDS domains, topics, QoS profiles and partitions within the DDS bus — the ZeroDDS equivalent of the RTI Routing Service, and the in-DDS counterpart to the protocol bridges (which cross protocol boundaries). Safety classification: COMFORT.

A route couples an input endpoint (a reader on a domain/topic) to an output endpoint (a writer on a — possibly different — domain/topic).

What it does

CapabilityDescription
Topic renaminginput topic A → output topic B
Domain bridgingread on domain 0, write on domain 1, in one process
QoS mappingper-endpoint reliability / durability / ownership / partition / data-representation
Type-agnostic byte forwardingthe CDR body is forwarded verbatim — representation-faithful (XCDR1/XCDR2 encapsulation preserved), no type recompilation, cross-vendor
Keyed-instance lifecycledispose / unregister events are forwarded for keyed topics (Spec §9.6.3.9)
Loop guardinput and output participants on a shared domain are made mutually invisible, so no router output is re-ingested by a router input — preventing router-internal forwarding loops while application writers stay visible
Content filteringa DDS SQL filter (temp > 50 AND zone = 'A') evaluated per sample against the decoded body
Field transformationrename / constant-set / drop members, mapping an input shape to an output shape

Surfaces

  • LibraryRouter::start / Router::start_with_types.
  • Config — JSON (RouterConfig::from_json) or XML (RouterConfig::from_xml, native ZeroDDS schema + an RTI-Routing-Service-compatible subset, easing migration from existing RTI deployments).
  • Daemon — the zerodds-router binary.
  • Metrics — per-route counters in the zerodds-monitor registry (rendered by the Prometheus exporter).

Daemon

# Validate a config without starting any DDS state.
zerodds-router validate --config router.json

# Run the router (byte forwarding + loop guard + QoS mapping).
zerodds-router run --config router.json

# Run with type shapes (needed for content filtering / field transformation).
zerodds-router run --config router.json --types shapes.json

SIGINT / Ctrl-C shuts the router down cleanly.

Config — JSON

{
  "name": "edge-to-core",
  "routes": [
    {
      "name": "telemetry",
      "input":  { "domain": 0, "topic": "Telemetry", "type_name": "sensors::Reading" },
      "output": { "domain": 1, "topic": "Telemetry", "type_name": "sensors::Reading",
                  "qos": { "durability": "transient_local" } },
      "filter": { "expression": "temp > 50" }
    }
  ]
}

Routes without a filter/transform forward bytes verbatim and need no type information. A route with a filter or transform needs the input/output type shape (the flat struct member layout) supplied via --types.

Limitations

  • preserve_source_timestamp is parsed but rejected at route build: the runtime user byte-path does not surface a sample's source timestamp, so the router cannot reproduce it — the option fails loudly rather than being silently ignored.
  • Filter / transform operate on flat @final / @appendable structs of scalar and string members (the common routing case). Nested structs, sequences, unions and @mutable member headers are a documented extension; byte pass-through routing has no such restriction.
  • Loop guard covers router-internal loops (within one process). Loops spanning two separate zerodds-router processes need a discovery discriminator (a router tag in user_data) — a documented follow-up.

See also

  • Bridges — cross-protocol gateways (the router crosses DDS-internal boundaries).
  • sql-filter — the SQL content-filter engine used by routes.
  • Vendor matrix — RTI Routing Service comparison.

Stability

1.0.0-rc.3.

zerodds-routing-service

In-DDS-Routing-Service. Leitet Samples zwischen DDS-Domains, Topics, QoS-Profilen und Partitions innerhalb des DDS-Busses weiter — das ZeroDDS-Äquivalent zum RTI Routing Service und das in-DDS-Gegenstück zu den Protokoll-Bridges (die Protokollgrenzen überschreiten). Safety-Klassifizierung: COMFORT.

Eine Route koppelt ein Input-Endpoint (ein Reader auf einer Domain/Topic) an ein Output-Endpoint (ein Writer auf einer — ggf. anderen — Domain/Topic).

Was es tut

FähigkeitBeschreibung
Topic-RenamingInput-Topic A → Output-Topic B
Domain-BridgingLesen auf Domain 0, Schreiben auf Domain 1, in einem Prozess
QoS-Mappingpro Endpoint Reliability / Durability / Ownership / Partition / Data-Representation
Typ-agnostisches Byte-Forwardingder CDR-Body wird unverändert weitergeleitet — repräsentations-treu (XCDR1/XCDR2-Encapsulation erhalten), keine Typ-Rekompilierung, cross-vendor
Keyed-Instance-LifecycleDispose-/Unregister-Events werden für keyed Topics weitergeleitet (Spec §9.6.3.9)
Loop-GuardInput- und Output-Participants auf gemeinsamer Domain werden gegenseitig unsichtbar gemacht, sodass kein Router-Output von einem Router-Input wieder aufgenommen wird — verhindert router-interne Forwarding-Loops, während Application-Writer sichtbar bleiben
Content-Filteringein DDS-SQL-Filter (temp > 50 AND zone = 'A'), pro Sample gegen den dekodierten Body ausgewertet
Field-TransformationMember umbenennen / konstant setzen / droppen — mappt eine Input-Shape auf eine Output-Shape

Oberflächen

  • LibraryRouter::start / Router::start_with_types.
  • Config — JSON (RouterConfig::from_json) oder XML (RouterConfig::from_xml, natives ZeroDDS-Schema + ein RTI-Routing-Service-kompatibles Subset, das die Migration aus bestehenden RTI-Deployments erleichtert).
  • Daemon — das zerodds-router-Binary.
  • Metriken — Pro-Route-Counter in der zerodds-monitor-Registry (vom Prometheus-Exporter gerendert).

Daemon

# Eine Config validieren, ohne DDS-State zu starten.
zerodds-router validate --config router.json

# Den Router starten (Byte-Forwarding + Loop-Guard + QoS-Mapping).
zerodds-router run --config router.json

# Mit Typ-Shapes starten (nötig für Content-Filtering / Field-Transformation).
zerodds-router run --config router.json --types shapes.json

SIGINT / Ctrl-C fährt den Router sauber herunter.

Config — JSON

{
  "name": "edge-to-core",
  "routes": [
    {
      "name": "telemetry",
      "input":  { "domain": 0, "topic": "Telemetry", "type_name": "sensors::Reading" },
      "output": { "domain": 1, "topic": "Telemetry", "type_name": "sensors::Reading",
                  "qos": { "durability": "transient_local" } },
      "filter": { "expression": "temp > 50" }
    }
  ]
}

Routes ohne filter/transform leiten Bytes unverändert weiter und brauchen keine Typ-Information. Eine Route mit Filter oder Transform braucht die Input-/Output-Typ-Shape (das flache Struct-Member-Layout), übergeben via --types.

Grenzen

  • preserve_source_timestamp wird geparst, aber beim Route-Build abgelehnt: der User-Byte-Pfad der Runtime gibt den Source-Timestamp eines Samples nicht heraus, sodass der Router ihn nicht reproduzieren kann — die Option scheitert laut, statt still ignoriert zu werden.
  • Filter / Transform arbeiten auf flachen @final/@appendable-Structs aus Skalar- und String-Membern (der häufige Routing-Fall). Nested Structs, Sequences, Unions und @mutable-Member-Header sind eine dokumentierte Erweiterung; Byte-Pass-Through-Routing hat diese Einschränkung nicht.
  • Loop-Guard deckt router-interne Loops ab (innerhalb eines Prozesses). Loops über zwei separate zerodds-router-Prozesse brauchen einen Discovery-Diskriminator (ein Router-Tag im user_data) — ein dokumentierter Follow-up.

Siehe auch

  • Bridges — cross-Protokoll-Gateways (der Router überschreitet DDS-interne Grenzen).
  • sql-filter — die SQL-Content-Filter-Engine, die Routes nutzen.
  • Vendor-Matrix — RTI-Routing-Service-Vergleich.

Stabilität

1.0.0-rc.3.