zerodds-amqp-bridge-daemon v1.0 — Spec Coverage
Source: docs/specs/zerodds-amqp-bridge-daemon-1.0.md
Implementation:
crates/amqp-endpoint/· docs.rs — AMQP bridge daemon endpoint.
§1 Conformance levels
§1 L1-L6 conformance matrix
Spec: §1 — six levels (Wire/DDS/Bridging/Config/Auth/Multi-Tenant); L1–L4 mandatory, L5–L6 optional.
Repo: —
Tests: —
Status: n/a (informative) — assignment of the levels; the requirements are the items §2 to §12.
§2 CLI surface
§2 zerodds-amqp-bridged CLI
Spec: §2 — options
--config/--broker/--container-id/--domain/--sasl-mechanism/--user/--password/--tls-*/--topic/--log-level/--metrics/--version/--help;
exit codes 0/1/2/3/4/5/6.
Repo: crates/amqp-endpoint/src/bin/zerodds-amqp-bridged.rs.
Tests: crates/amqp-endpoint/tests/bridge_e2e.rs::version_flag_emits_one_line_and_exits_zero,
::missing_broker_url_fails_with_exit_1,
::daemon_with_no_broker_fails_with_exit_2,
::a_broker_without_the_sasl_layer_is_refused_by_name (exit 5),
::plain_without_tls_is_refused_towards_a_remote_broker (exit 1).
Status: done
§3 Config-file format
§3 YAML loader with ENV substitution
Spec: §3 — top-level domain/amqp/topics/acl/metrics/catalog;
ENV substitution ${VAR} and ${VAR:-default}.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (DaemonConfig::from_config, read_topic),
crates/config/src/parse.rs (the shared parser, flat flow maps).
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::{the_spec_example_loads, what_the_daemon_would_not_honour_is_refused, the_shipped_example_reads_as_it_says, values_the_shared_parser_reads_reach_the_daemon};
crates/config/tests/layering.rs::{a_flat_flow_map_is_a_map, a_hash_inside_quotes_is_part_of_the_value, environment_references_expand_before_the_parse}.
Status: done
§4 AMQP wire protocol
§4.1 Connection open with properties + capabilities
Spec: §4.1 — OPEN with container-id/hostname/max-frame-size/
channel-max/idle-time-out/properties/desired + offered capabilities.
Repo: crates/amqp-endpoint/src/broker.rs (connect, open_body), crates/amqp-endpoint/src/bridge_daemon.rs::run.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages
(RabbitMQ accepts the open), crates/amqp-endpoint/tests/broker_tls_sasl.rs (the test server reads the open).
Status: done
§4.2 Session + link setup ATTACH
Spec: §4.2 — ATTACH per direction with name/source/target,
settle modes, properties, desired capabilities; one session per link.
Repo: crates/amqp-endpoint/src/broker.rs (BrokerWriter::begin, attach), crates/amqp-endpoint/src/bridge_daemon.rs (link_spec,
LinkState, begin_all).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_refused_link_leaves_the_others_running_and_catalog_and_ttl_arrive
(RabbitMQ ends the session of the refused address, the others keep
running), crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::after_the_broker_closes_the_connection_the_bridge_reconnects.
Status: done
§4.3 TRANSFER frame DDS→AMQP
Spec: §4.3 — a message per DDS-AMQP 1.0 §8: header, properties,
dds:* application properties, a Pass-Through body with the encapsulation
header; multi-frame above max-frame-size.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (encode_message, drain), crates/amqp-endpoint/src/broker.rs (BrokerWriter::transfer),
crates/amqp-endpoint/src/properties.rs.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::{a_sample_round_trips_through_the_message_form, an_xcdr1_sample_keeps_its_header_and_says_so};
crates/amqp-endpoint/src/broker.rs::tests::a_message_above_the_frame_size_is_split_and_reassembled;
against RabbitMQ 4.0.5 crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::{dds_samples_arrive_in_the_queue_as_pass_through_messages, a_sample_larger_than_the_frame_size_crosses_in_both_directions}.
Status: done
§4.4 TRANSFER frame AMQP→DDS + DISPOSITION
Spec: §4.4 — receiver link with FLOW credit, body → DDS sample,
DISPOSITION accepted/rejected/released.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (deliver, decode_message, split_encapsulation),
crates/amqp-endpoint/src/broker.rs (BrokerReader::next_event, reassembly).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not
(accepted and rejected, the queue empty afterwards),
crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_sample_larger_than_the_frame_size_crosses_in_both_directions
(loop prevention and multi-frame receive).
Status: done
§4.5 Disposition mapping accepted/rejected/released/modified
Spec: §4.5 — the broker’s outcome of unsettled deliveries.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::on_inbound (Inbound::Disposition), crates/amqp-endpoint/src/broker.rs (decode_outcome).
Tests: crates/amqp-endpoint/src/broker.rs::tests::outcomes_round_trip_through_their_described_form;
accepted against RabbitMQ in crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages.
released/modified/rejected from a broker are not measured.
Status: partial — released/modified/rejected from a broker are not measured.
## §5 Topic mapping
§5.1 Address
Spec: §5.1 — amqp_address per topic, broker-specific.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::read_topic.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::what_the_daemon_would_not_honour_is_refused;
RabbitMQ v2 addresses (/queues/…) in crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs.
Status: done
§5.2 Catalog
Spec: §5.2 — a catalog (JSON) per connection on its own address.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (catalog_message, DaemonConfig::catalog_json,
catalog_address).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_refused_link_leaves_the_others_running_and_catalog_and_ttl_arrive
(pika reads the catalog from /queues/zd_bridge_catalog).
Status: done
§6 QoS translation
§6 DDS QoS → AMQP behaviour map
Spec: §6 — reliability/durability/history/lifespan/deadline/ liveliness/partition.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (read_topic: BEST_EFFORT → settled; encode_message:
durable, ttl; OutLink::cap), crates/amqp-endpoint/src/broker.rs::BrokerWriter::heartbeat.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_spec_example_loads (BEST_EFFORT → settled);
crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_refused_link_leaves_the_others_running_and_catalog_and_ttl_arrive
(LIFESPAN 60 s → expiration 60000).
Open: the deadline annotation, the partition filter; KEEP_ALL drops the oldest sample beyond 65 536 waiting ones instead of back-pressure.
Status: partial — the deadline annotation and the partition filter are missing; KEEP_ALL drops the oldest beyond 65 536 waiting samples. ## §7 Security
§7.1 TLS amqps:// + ALPN
Spec: §7.1 — amqps:// per amqp.tls.enabled, ALPN ["amqp"].
Repo: crates/amqp-endpoint/src/broker.rs (Wire::Tls, ALPN_AMQP), crates/amqp-endpoint/src/bridge_daemon.rs::tls_config.
Tests: crates/amqp-endpoint/tests/broker_tls_sasl.rs::external_authenticates_with_the_tls_client_certificate_and_alpn_amqp
(the server reads amqp as the agreed protocol).
Status: done
§7.1a ALPN negotiation ["amqp"]
Spec: §7.1 — the TLS handshake offers ALPN ["amqp"].
Repo: crates/amqp-endpoint/src/broker.rs::connect.
Tests: crates/amqp-endpoint/tests/broker_tls_sasl.rs::external_authenticates_with_the_tls_client_certificate_and_alpn_amqp (the server reads amqp as the negotiated protocol).
Status: done
§7.2 SASL PLAIN/SCRAM/EXTERNAL/ANONYMOUS/XOAUTH2
Spec: §7.2 — the mechanism per config; PLAIN only over TLS, ANONYMOUS only towards loopback.
Repo: crates/amqp-endpoint/src/broker.rs (sasl, scram_client_final), crates/amqp-endpoint/src/bridge_daemon.rs (DaemonConfig::sasl,
the checks in run).
Tests: crates/amqp-endpoint/src/broker.rs::tests::scram_client_final_matches_the_rfc_7677_example;
crates/amqp-endpoint/tests/broker_tls_sasl.rs::{scram_sha_256_authenticates_and_a_wrong_password_is_refused, external_authenticates_with_the_tls_client_certificate_and_alpn_amqp, a_mechanism_the_broker_does_not_offer_is_refused_by_name};
PLAIN against RabbitMQ in crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs;
crates/amqp-endpoint/tests/bridge_e2e.rs::{plain_without_tls_is_refused_towards_a_remote_broker, a_broker_without_the_sasl_layer_is_refused_by_name}.
XOAUTH2 is not measured against a broker; SCRAM-SHA-512 is not built.
Status: partial — XOAUTH2 not measured against a broker; SCRAM-SHA-512 not built. ### §7.3 ACL daemon side
Spec: §7.3 — subject = SASL identity; filter before TRANSFER.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (allowed, acl.rules, acl.default_deny).
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_shipped_example_reads_as_it_says (the rules
are read). No test checks that a denied direction moves no data.
Status: partial — no test checks that a denied direction moves no data. ## §8 Operations + observability
§8.1 Structured JSON logging
Spec: §8.1 — JSON log on stdout with timestamp/level/event/… and
--log-level.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (log, event_level, LOG_LEVEL).
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::every_event_has_a_level_and_the_threshold_orders_them.
Open: the lines go to stderr, without timestamp, container_id,
delivery_id, latency_us.
Status: partial — lines on stderr, without timestamp, container_id, delivery_id, latency_us.
### §8.2 Prometheus metrics
Spec: §8.2 — 13 families zerodds_amqp_bridge_* with labels.
Repo: crates/amqp-endpoint/src/daemon_runtime.rs (BridgeMetrics),
crates/amqp-endpoint/src/bridge_daemon.rs (the counting sites).
Tests: crates/amqp-endpoint/src/daemon_runtime.rs::tests,
crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::the_metrics_of_section_8_2_count_transfers_dispositions_and_samples
(Linux test host, RabbitMQ 4.0.5: 3 samples out, one good and one broken message
in; transfers, samples and dispositions per topic,
rejected{reason="amqp:decode-error"} 1).
Status: done — all 13 families; dispositions count in both
directions, reason is the AMQP condition (amqp:*, else other). The
generic zerodds_amqp_* remain beside them.
### §8.3 OTLP spans
Spec: §8.3 — OTEL_EXPORTER_OTLP_ENDPOINT enables the TRANSFER
round-trip span.
Repo: crates/amqp-endpoint/src/daemon_runtime.rs (OTLP init via
zerodds-observability-otlp), crates/amqp-endpoint/src/link.rs (span
emit per TRANSFER).
Tests: crates/amqp-endpoint/src/daemon_runtime.rs::tests::otlp_config_parses_endpoint — the endpoint from
OTEL_EXPORTER_OTLP_ENDPOINT is read. Nothing tests that a span is emitted
per TRANSFER — see §8.3a.
Status: partial — the configuration is covered, the span emit is not; the
missing half is carried as §8.3a open.
## §9 Lifecycle
§8.3a TRANSFER roundtrip span
Spec: §8.3 — with OTEL_EXPORTER_OTLP_ENDPOINT set, one roundtrip span
is emitted per TRANSFER.
Repo: —
Tests: —
Status: open — the emit half of §8.3. Only reading the endpoint configuration is covered.
§9.1 Startup sequence
Spec: §9.1 — config → TLS → DCPS → reader/writer → open + SASL + TLS → session + attach → signal handler.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::run, crates/amqp-endpoint/src/bin/zerodds-amqp-bridged.rs.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not (RabbitMQ 4.0, #[ignore], Linux test host).
Status: partial — every case of bridge_rabbitmq_e2e.rs starts the bridge via run and carries data; no test checks the order of the steps.
§9.2 Shutdown SIGTERM/SIGINT/SIGHUP
Spec: §9.2 — graceful drain of at most 30 s, DETACH/END/CLOSE; SIGHUP TLS + ACL reload.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::pump (DRAIN_BUDGET), crates/amqp-endpoint/src/bridge_daemon.rs::run (DETACH/END/CLOSE);
crates/amqp-endpoint/src/bridge_daemon.rs::run_with_reload, ::apply_reload
(the ACL and the TLS material of the next connect; withdrawn rights apply
at once, new grants after a restart).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_reload_that_withdraws_the_read_right_stops_the_topic
(RabbitMQ 4.0, Linux test host); no test for the drain; the stop through the flag
runs in every case of crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs.
Status: partial — no test for the drain.
§9.3 Reconnect
Spec: §9.3 — exponential back-off; unsettled deliveries sent again.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (next_delay, the requeue in run and out_link_down).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::after_the_broker_closes_the_connection_the_bridge_reconnects
(rabbitmqctl close_all_connections, both samples arrive in order).
Status: done
§10 Cross-vendor
§10 RTPS peer + RabbitMQ/Artemis/Qpid/Solace/ServiceBus
Spec: §10 — a plain RTPS peer; the AMQP side against five brokers.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs, crates/amqp-endpoint/src/broker.rs, crates/amqp-endpoint/src/coexistence.rs.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_sample_larger_than_the_frame_size_crosses_in_both_directions (RabbitMQ 4.0.5, Linux test host); Artemis, Qpid-Dispatch, Solace, Azure ServiceBus: not measured (§10a).
Status: partial — RabbitMQ 4.0.5 measured, the four other brokers not (§10a). ### §10a Broker matrix Artemis/Qpid Dispatch/Solace/Azure ServiceBus
Spec: §10 — the AMQP side against Artemis, Qpid Dispatch, Solace and Azure ServiceBus.
Repo: —
Tests: —
Status: open — the part of §10 and §12.3 beyond RabbitMQ.
§11 Packaging
§11 Linux/macOS/Windows/Docker layout
Spec: §11 — binary zerodds-amqp-bridged; configs/services/Docker;
manuals.
Repo: packaging/linux/systemd/zerodds-amqp-bridged.service,
packaging/macos/launchd/org.zerodds.amqp-bridged.plist,
packaging/macos/homebrew/zerodds-amqp-bridge.rb,
packaging/windows/services/Install-Services.ps1,
packaging/docker/amqp-bridged/,
packaging/linux/configs/amqp-bridged.yaml.example,
man/man1/zerodds-amqp-bridged.1, man/man5/zerodds-amqp-bridged.yaml.5.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_shipped_example_reads_as_it_says
(the shipped example configuration through the real parser, with the values it states);
tools/traceability/tests/bridge_config_manpages.rs::{every_example_key_is_documented_in_the_man_page, the_man_page_names_no_key_the_example_does_not_declare, the_pre_spec_vocabulary_is_gone_from_pages_and_examples, every_man_page_names_its_parser_and_what_an_unknown_key_does}
(the manual page and the example file name the same keys).
Status: done
§12 Testing
§12.1 Unit tests per module
Spec: §12.1 — config/amqp_codec/link_state/disposition/sasl/ dds_pump/acl, ≥ 5 tests each.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs, crates/amqp-endpoint/src/broker.rs, the modules under crates/amqp-endpoint/src/.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_spec_example_loads, crates/amqp-endpoint/src/link.rs::tests::deliver_without_credit_yields_error, crates/amqp-endpoint/src/sasl.rs::tests::plain_fails_on_wrong_credentials, crates/amqp-endpoint/src/dds_bridge.rs::tests::accept_all_returns_accepted_for_every_operation, crates/amqp-endpoint/src/bridge_security.rs::tests::amqp_acl_address_check; tests per module: link 13, sasl 18, dds_bridge 8, bridge_security 5, config_xml 13, bridge_daemon 8.
Status: done
§12.2 Integration tests
Spec: §12.2 — the daemon against RabbitMQ, round trip + DISPOSITION sequence.
Repo: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs, crates/amqp-endpoint/tests/broker_tls_sasl.rs, crates/amqp-endpoint/tests/bridge_e2e.rs.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not, crates/amqp-endpoint/tests/broker_tls_sasl.rs::scram_sha_256_authenticates_and_a_wrong_password_is_refused, crates/amqp-endpoint/tests/bridge_e2e.rs::a_broker_without_the_sasl_layer_is_refused_by_name (the RabbitMQ cases are #[ignore], Linux test host).
Status: done
§12.3 Multi-vendor
Spec: §12.3 — Cyclone DDS subscriber + RabbitMQ + bridge; broker matrix.
Repo: —
Tests: —
Open: a Cyclone subscriber behind the bridge, brokers beyond RabbitMQ.
Status: open — a Cyclone subscriber behind the bridge and brokers beyond RabbitMQ are not measured. ## §13 Cross-references
§13 Related library + OMG spec + standards
Spec: §13 — library crates/amqp-bridge/ + crates/amqp-endpoint/,
OMG DDS-AMQP-1.0, ISO/IEC 19464:2014, wire format, deployment.
Repo: —
Tests: —
Status: n/a (informative) — reference list.
§14 Versioning
§14 SemVer bump rules
Spec: §14 — patch=bugfixes, minor=additive config, major=wire-protocol change (AMQP-1.0→2).
Repo: —
Tests: —
Status: n/a (informative) — rule for assigning the version number of a release, not a property of the daemon.
Audit status
15 done / 9 partial / 3 open / 0 blocked / 3 n/a (informative).
Open items: zerodds-amqp-bridge-daemon-1.0.open.en.md.
zerodds-amqp-bridge-daemon v1.0 — Spec-Coverage
Quelle: docs/specs/zerodds-amqp-bridge-daemon-1.0.md
Implementation:
crates/amqp-endpoint/· docs.rs — AMQP-Bridge-Daemon-Endpoint.
§1 Conformance-Levels
§1 L1-L6 Conformance-Matrix
Spec: §1 — sechs Levels (Wire/DDS/Bridging/Config/Auth/Multi- Tenant); L1–L4 Pflicht, L5–L6 optional.
Repo: —
Tests: —
Status: n/a (informative) — Zuordnung der Levels; die Anforderungen sind die Items §2 bis §12.
§2 CLI-Surface
§2 zerodds-amqp-bridged CLI
Spec: §2 — Optionen --config/--broker/--container-id/
--domain/--sasl-mechanism/--user/--password/--tls-*/--topic/
--log-level/--metrics/--version/--help; Exit-Codes 0/1/2/3/4/5/6.
Repo: crates/amqp-endpoint/src/bin/zerodds-amqp-bridged.rs.
Tests: crates/amqp-endpoint/tests/bridge_e2e.rs::version_flag_emits_one_line_and_exits_zero,
::missing_broker_url_fails_with_exit_1,
::daemon_with_no_broker_fails_with_exit_2,
::a_broker_without_the_sasl_layer_is_refused_by_name (Exit 5),
::plain_without_tls_is_refused_towards_a_remote_broker (Exit 1).
Status: done
§3 Config-File-Format
§3 YAML-Loader mit ENV-Substitution
Spec: §3 — Top-Level domain/amqp/topics/acl/metrics/catalog;
ENV-Substitution ${VAR} und ${VAR:-default}.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (DaemonConfig::from_config, read_topic),
crates/config/src/parse.rs (gemeinsamer Parser, flache Flow-Maps).
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::{the_spec_example_loads, what_the_daemon_would_not_honour_is_refused, the_shipped_example_reads_as_it_says, values_the_shared_parser_reads_reach_the_daemon};
crates/config/tests/layering.rs::{a_flat_flow_map_is_a_map, a_hash_inside_quotes_is_part_of_the_value, environment_references_expand_before_the_parse}.
Status: done
§4 AMQP-Wire-Protocol
§4.1 Connection-Open mit Properties + Capabilities
Spec: §4.1 — OPEN mit container-id/hostname/max-frame-size/
channel-max/idle-time-out/properties/desired-+offered-capabilities.
Repo: crates/amqp-endpoint/src/broker.rs (connect, open_body), crates/amqp-endpoint/src/bridge_daemon.rs::run.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages
(RabbitMQ nimmt das open an), crates/amqp-endpoint/tests/broker_tls_sasl.rs (Test-Server liest das open).
Status: done
§4.2 Session + Link-Setup ATTACH
Spec: §4.2 — ATTACH pro Richtung mit name/source/target,
settle-modes, properties, desired-capabilities; eine Session pro Link.
Repo: crates/amqp-endpoint/src/broker.rs (BrokerWriter::begin, attach), crates/amqp-endpoint/src/bridge_daemon.rs (link_spec,
LinkState, begin_all).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_refused_link_leaves_the_others_running_and_catalog_and_ttl_arrive
(RabbitMQ beendet die Session der abgewiesenen Adresse, die anderen laufen
weiter), crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::after_the_broker_closes_the_connection_the_bridge_reconnects.
Status: done
§4.3 TRANSFER-Frame DDS→AMQP
Spec: §4.3 — Message nach DDS-AMQP 1.0 §8: Header, Properties
(dds:*-ApplicationProperties), Pass-Through-Body mit
Encapsulation-Header; mehrteilig über max-frame-size.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (encode_message, drain), crates/amqp-endpoint/src/broker.rs (BrokerWriter::transfer),
crates/amqp-endpoint/src/properties.rs.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::{a_sample_round_trips_through_the_message_form, an_xcdr1_sample_keeps_its_header_and_says_so};
crates/amqp-endpoint/src/broker.rs::tests::a_message_above_the_frame_size_is_split_and_reassembled;
gegen RabbitMQ 4.0.5 crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::{dds_samples_arrive_in_the_queue_as_pass_through_messages, a_sample_larger_than_the_frame_size_crosses_in_both_directions}.
Status: done
§4.4 TRANSFER-Frame AMQP→DDS + DISPOSITION
Spec: §4.4 — Receiver-Link mit FLOW-Credit, Body→DDS-Sample,
DISPOSITION accepted/rejected/released.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (deliver, decode_message, split_encapsulation),
crates/amqp-endpoint/src/broker.rs (BrokerReader::next_event, Reassemblierung).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not
(accepted und rejected, Queue danach leer),
crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_sample_larger_than_the_frame_size_crosses_in_both_directions
(Schleifensperre und mehrteiliger Empfang).
Status: done
§4.5 Disposition-Mapping accepted/rejected/released/modified
Spec: §4.5 — Outcome des Brokers auf unbestätigte Deliveries.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::on_inbound (Inbound::Disposition), crates/amqp-endpoint/src/broker.rs (decode_outcome).
Tests: crates/amqp-endpoint/src/broker.rs::tests::outcomes_round_trip_through_their_described_form;
accepted gegen RabbitMQ in crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages.
released/modified/rejected vom Broker sind nicht gegen einen Broker
gemessen.
Status: partial — released/modified/rejected vom Broker sind nicht gegen einen Broker gemessen.
## §5 Topic-Mapping
§5.1 Address
Spec: §5.1 — amqp_address pro Topic, Broker-spezifisch.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::read_topic.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::what_the_daemon_would_not_honour_is_refused;
RabbitMQ-v2-Adressen (/queues/…) in crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs.
Status: done
§5.2 Catalog
Spec: §5.2 — Catalog (JSON) pro Verbindung auf eigener Adresse.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (catalog_message, DaemonConfig::catalog_json,
catalog_address).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_refused_link_leaves_the_others_running_and_catalog_and_ttl_arrive
(pika liest den Catalog aus /queues/zd_bridge_catalog).
Status: done
§6 QoS-Translation
§6 DDS-QoS → AMQP-Behavior Map
Spec: §6 — Reliability/Durability/History/Lifespan/Deadline/ Liveliness/Partition.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (read_topic: BEST_EFFORT → settled; encode_message:
durable, ttl; OutLink::cap), crates/amqp-endpoint/src/broker.rs::BrokerWriter::heartbeat.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_spec_example_loads (BEST_EFFORT → settled);
crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_refused_link_leaves_the_others_running_and_catalog_and_ttl_arrive
(LIFESPAN 60 s → expiration 60000).
Offen: Deadline-Annotation, Partition-Filter; KEEP_ALL verwirft über 65 536 wartenden Samples das älteste statt Backpressure.
Status: partial — Deadline-Annotation und Partition-Filter fehlen; KEEP_ALL verwirft über 65 536 wartenden Samples das älteste. ## §7 Security
§7.1 TLS amqps:// + ALPN
Spec: §7.1 — amqps:// per amqp.tls.enabled, ALPN ["amqp"].
Repo: crates/amqp-endpoint/src/broker.rs (Wire::Tls, ALPN_AMQP), crates/amqp-endpoint/src/bridge_daemon.rs::tls_config.
Tests: crates/amqp-endpoint/tests/broker_tls_sasl.rs::external_authenticates_with_the_tls_client_certificate_and_alpn_amqp
(der Server liest amqp als ausgehandeltes Protokoll).
Status: done
§7.1a ALPN-Aushandlung ["amqp"]
Spec: §7.1 — der TLS-Handshake bietet ALPN ["amqp"] an.
Repo: crates/amqp-endpoint/src/broker.rs::connect.
Tests: crates/amqp-endpoint/tests/broker_tls_sasl.rs::external_authenticates_with_the_tls_client_certificate_and_alpn_amqp (der Server liest amqp als ausgehandeltes Protokoll).
Status: done
§7.2 SASL PLAIN/SCRAM/EXTERNAL/ANONYMOUS/XOAUTH2
Spec: §7.2 — Mechanismus pro Config; PLAIN nur über TLS, ANONYMOUS nur gegen Loopback.
Repo: crates/amqp-endpoint/src/broker.rs (sasl, scram_client_final), crates/amqp-endpoint/src/bridge_daemon.rs (DaemonConfig::sasl,
Prüfungen in run).
Tests: crates/amqp-endpoint/src/broker.rs::tests::scram_client_final_matches_the_rfc_7677_example;
crates/amqp-endpoint/tests/broker_tls_sasl.rs::{scram_sha_256_authenticates_and_a_wrong_password_is_refused, external_authenticates_with_the_tls_client_certificate_and_alpn_amqp, a_mechanism_the_broker_does_not_offer_is_refused_by_name};
PLAIN gegen RabbitMQ in crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs;
crates/amqp-endpoint/tests/bridge_e2e.rs::{plain_without_tls_is_refused_towards_a_remote_broker, a_broker_without_the_sasl_layer_is_refused_by_name}.
XOAUTH2 ist nicht gegen einen Broker gemessen; SCRAM-SHA-512 ist nicht gebaut.
Status: partial — XOAUTH2 nicht gegen einen Broker gemessen; SCRAM-SHA-512 nicht gebaut. ### §7.3 ACL Daemon-Side
Spec: §7.3 — Subject = SASL-Identity; Filter vor TRANSFER.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (allowed, acl.rules, acl.default_deny).
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_shipped_example_reads_as_it_says (Regeln
gelesen). Kein Test prüft, dass eine verweigerte Richtung keine Daten
bewegt.
Status: partial — kein Test prüft, dass eine verweigerte Richtung keine Daten bewegt. ## §8 Operations + Observability
§8.1 Strukturiertes JSON-Logging
Spec: §8.1 — JSON-Log auf stdout mit timestamp/level/event/… und
--log-level.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (log, event_level, LOG_LEVEL).
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::every_event_has_a_level_and_the_threshold_orders_them.
Offen: die Zeilen gehen auf stderr, ohne timestamp, container_id,
delivery_id, latency_us.
Status: partial — Zeilen auf stderr, ohne timestamp, container_id, delivery_id, latency_us.
### §8.2 Prometheus-Metrics
Spec: §8.2 — 13 Familien zerodds_amqp_bridge_* mit Labels.
Repo: crates/amqp-endpoint/src/daemon_runtime.rs (BridgeMetrics),
crates/amqp-endpoint/src/bridge_daemon.rs (Zählstellen).
Tests: crates/amqp-endpoint/src/daemon_runtime.rs::tests,
crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::the_metrics_of_section_8_2_count_transfers_dispositions_and_samples
(Linux-Testhost, RabbitMQ 4.0.5: 3 Samples hinaus, eine gute und eine kaputte
Nachricht herein; Transfers, Samples und Dispositionen pro Topic,
rejected{reason="amqp:decode-error"} 1).
Status: done — alle 13 Familien; Dispositionen zählen in beiden
Richtungen, reason ist die AMQP-Condition (amqp:*, sonst other).
Daneben bleiben die generischen zerodds_amqp_*.
### §8.3 OTLP-Spans
Spec: §8.3 — OTEL_EXPORTER_OTLP_ENDPOINT aktiviert
TRANSFER-Roundtrip-Span.
Repo: crates/amqp-endpoint/src/daemon_runtime.rs (OTLP-Init via
zerodds-observability-otlp),
crates/amqp-endpoint/src/link.rs (Span-Emit pro TRANSFER).
Tests: crates/amqp-endpoint/src/daemon_runtime.rs::tests::otlp_config_parses_endpoint — der Endpoint aus
OTEL_EXPORTER_OTLP_ENDPOINT wird gelesen. Dass pro TRANSFER ein Span
entsteht, prüft kein Test — siehe §8.3a.
Status: partial — die Konfiguration ist geprüft, der Span-Emit nicht; der
fehlende Teil wird als §8.3a open geführt.
## §9 Lifecycle
§8.3a TRANSFER-Roundtrip-Span
Spec: §8.3 — bei gesetztem OTEL_EXPORTER_OTLP_ENDPOINT entsteht pro
TRANSFER ein Roundtrip-Span.
Repo: —
Tests: —
Status: open — der Emit-Teil von §8.3. Geprüft ist nur, dass die Endpoint-Konfiguration gelesen wird.
§9.1 Startup-Sequence
Spec: §9.1 — Config → TLS → DCPS → Reader/Writer → Open + SASL + TLS → Session + Attach → Signal-Handler.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::run, crates/amqp-endpoint/src/bin/zerodds-amqp-bridged.rs.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not (RabbitMQ 4.0, #[ignore], Linux-Testhost).
Status: partial — jeder Fall von bridge_rabbitmq_e2e.rs startet die Bridge über run und überträgt Daten; kein Test prüft die Reihenfolge der Schritte.
§9.2 Shutdown SIGTERM/SIGINT/SIGHUP
Spec: §9.2 — Graceful Drain max 30 s, DETACH/END/CLOSE; SIGHUP TLS+ACL-Reload.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs::pump (DRAIN_BUDGET), crates/amqp-endpoint/src/bridge_daemon.rs::run (DETACH/END/CLOSE);
crates/amqp-endpoint/src/bridge_daemon.rs::run_with_reload, ::apply_reload
(ACL und das TLS-Material des nächsten Connects; entzogene Rechte gelten
sofort, neu erteilte nach einem Neustart).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_reload_that_withdraws_the_read_right_stops_the_topic
(RabbitMQ 4.0, Linux-Testhost); kein Test für den Drain; der Stopp über das Flag
läuft in jedem Fall von crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs.
Status: partial — kein Test für den Drain.
§9.3 Reconnect
Spec: §9.3 — Exponential-Backoff; unbestätigte Deliveries erneut.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs (next_delay, Requeue in run und out_link_down).
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::after_the_broker_closes_the_connection_the_bridge_reconnects
(rabbitmqctl close_all_connections, beide Samples kommen in Reihenfolge an).
Status: done
§10 Cross-Vendor
§10 RTPS-Peer + RabbitMQ/Artemis/Qpid/Solace/ServiceBus
Spec: §10 — normaler RTPS-Peer; AMQP-Seite gegen fünf Broker.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs, crates/amqp-endpoint/src/broker.rs, crates/amqp-endpoint/src/coexistence.rs.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_sample_larger_than_the_frame_size_crosses_in_both_directions (RabbitMQ 4.0.5, Linux-Testhost); Artemis, Qpid-Dispatch, Solace, Azure ServiceBus: nicht gemessen (§10a).
Status: partial — RabbitMQ 4.0.5 gemessen, die vier weiteren Broker nicht (§10a). ### §10a Broker-Matrix Artemis/Qpid-Dispatch/Solace/Azure ServiceBus
Spec: §10 — die AMQP-Seite gegen Artemis, Qpid-Dispatch, Solace und Azure ServiceBus.
Repo: —
Tests: —
Status: open — der Teil von §10 und §12.3 jenseits RabbitMQ.
§11 Packaging
§11 Linux/macOS/Windows/Docker Layout
Spec: §11 — Binary zerodds-amqp-bridged; Configs/Services/Docker;
Manuals.
Repo: packaging/linux/systemd/zerodds-amqp-bridged.service,
packaging/macos/launchd/org.zerodds.amqp-bridged.plist,
packaging/macos/homebrew/zerodds-amqp-bridge.rb,
packaging/windows/services/Install-Services.ps1,
packaging/docker/amqp-bridged/,
packaging/linux/configs/amqp-bridged.yaml.example,
man/man1/zerodds-amqp-bridged.1,
man/man5/zerodds-amqp-bridged.yaml.5.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_shipped_example_reads_as_it_says
(die ausgelieferte Beispiel-Konfiguration durch den echten Parser, mit den Werten, die sie nennt);
tools/traceability/tests/bridge_config_manpages.rs::{every_example_key_is_documented_in_the_man_page, the_man_page_names_no_key_the_example_does_not_declare, the_pre_spec_vocabulary_is_gone_from_pages_and_examples, every_man_page_names_its_parser_and_what_an_unknown_key_does}
(die Handbuchseite und die Beispieldatei nennen dieselben Schlüssel).
Status: done
§12 Testing
§12.1 Unit-Tests pro Modul
Spec: §12.1 — config/amqp_codec/link_state/disposition/sasl/ dds_pump/acl je ≥ 5 Tests.
Repo: crates/amqp-endpoint/src/bridge_daemon.rs, crates/amqp-endpoint/src/broker.rs, die Module unter crates/amqp-endpoint/src/.
Tests: crates/amqp-endpoint/src/bridge_daemon.rs::tests::the_spec_example_loads, crates/amqp-endpoint/src/link.rs::tests::deliver_without_credit_yields_error, crates/amqp-endpoint/src/sasl.rs::tests::plain_fails_on_wrong_credentials, crates/amqp-endpoint/src/dds_bridge.rs::tests::accept_all_returns_accepted_for_every_operation, crates/amqp-endpoint/src/bridge_security.rs::tests::amqp_acl_address_check; Anzahl Tests je Modul: link 13, sasl 18, dds_bridge 8, bridge_security 5, config_xml 13, bridge_daemon 8.
Status: done
§12.2 Integration-Tests
Spec: §12.2 — Daemon gegen RabbitMQ, Roundtrip + DISPOSITION-Folge.
Repo: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs, crates/amqp-endpoint/tests/broker_tls_sasl.rs, crates/amqp-endpoint/tests/bridge_e2e.rs.
Tests: crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::dds_samples_arrive_in_the_queue_as_pass_through_messages, crates/amqp-endpoint/tests/bridge_rabbitmq_e2e.rs::a_message_published_by_pika_reaches_a_dds_reader_and_a_bad_body_does_not, crates/amqp-endpoint/tests/broker_tls_sasl.rs::scram_sha_256_authenticates_and_a_wrong_password_is_refused, crates/amqp-endpoint/tests/bridge_e2e.rs::a_broker_without_the_sasl_layer_is_refused_by_name (die RabbitMQ-Fälle sind #[ignore], Linux-Testhost).
Status: done
§12.3 Multi-Vendor
Spec: §12.3 — Cyclone-DDS-Subscriber + RabbitMQ + Bridge; Broker-Matrix.
Repo: —
Tests: —
Offen: Cyclone-Subscriber hinter der Bridge, Broker jenseits RabbitMQ.
Status: open — Cyclone-Subscriber hinter der Bridge und Broker jenseits RabbitMQ nicht gemessen. ## §13 Cross-References
§13 Verwandte Library + OMG-Spec + Standards
Spec: §13 — Library crates/amqp-bridge/ + crates/amqp-endpoint/,
OMG-DDS-AMQP-1.0, ISO/IEC 19464:2014, Wire-Format, Deployment.
Repo: —
Tests: —
Status: n/a (informative) — Verweisliste.
§14 Versioning
§14 SemVer-Bump-Regeln
Spec: §14 — Patch=Bugfixes, Minor=additive Config, Major=Wire- Protocol-Change (AMQP-1.0→2).
Repo: —
Tests: —
Status: n/a (informative) — Regel für die Vergabe der Versionsnummer eines Release, keine Eigenschaft des Daemons.
Audit-Status
15 done / 9 partial / 3 open / 0 blocked / 3 n/a (informative).
Offene Punkte: zerodds-amqp-bridge-daemon-1.0.open.md.