zerodds-webdds-bridge

OMG DDS-WEB 1.0 gateway daemon: REST-PSM (zerodds-web) + SOAP-PSM (zerodds-soap), one process, backed by zerodds-dcps.

The OMG Web-Enabled DDS 1.0 (formal/2014-12-01) gateway daemon, zerodds-webdds-bridged. Serves the REST PSM (§8.3, zerodds-web) and the SIMPLE-WSDL-SOAP PSM (§8.4, zerodds-soap) from one process on one HTTP port — two platform mappings of the same WebDDS object model (Spec §1.5), backed by the public typed API of zerodds-dcps.

zerodds-web and zerodds-soap are pure no_std + alloc libraries: routing, status-code mapping, XML element-tag registries, SOAP envelope/fault/WSDL codecs. Neither implements an HTTP server, a DdsBackend, or a body codec. This crate is that caller layer.

Modules

  • gateway::Gateway — impl zerodds_web::bridge::DdsBackend on the typed API of zerodds-dcps; covers every §7.4 entity operation, write/read for samples and the WaitSet operations (§7.4.9's long-poll WaitSet::get).
  • qos_update — turns a PUT body's inline <qos> or a <qos_profile> reference into the target entity's QoS, merged onto its current QoS.
  • contained_entities — the nested <publishers>/<subscribers>/<data_writers>/<data_readers> a create or update body may carry.
  • types_registry::TypeRegistry — resolves a topic's wire type from a config-named .idl file, or from a peer's TypeLookup discovery.
  • dynxml — converts a DynamicData sample to and from the DDS-WEB §8.1 XML representation, driven by the type's own descriptor.
  • metadata::MetadataStore — §7.3.1 Root metadata (QosLibrary/QosProfile/Type CRUD).
  • wsdl_bridge — builds the SOAP WSDL from the DDS-WEB object-model operations plus every config-named IDL interface's own operations.
  • rest_service / soap_service — request dispatch.
  • http1 — a hand-rolled HTTP/1.1 engine; no framework dependency.
  • daemon — config, CLI, security and server, the same shape as every other zerodds-*-bridged daemon.

Quickstart

zerodds-webdds-bridged --config /etc/zerodds/webdds-bridged.yaml

or, for a quick local run without a config file:

zerodds-webdds-bridged --listen 127.0.0.1:8080 --domain 0 \
  --type 'Demo::Sensor=/path/to/sensor.idl'

Every REST request needs Accept: application/dds-web+xml (Spec §8.3.5 Tab 7 — the only representation this gateway serves; a missing Accept is 400, one naming no served representation is 406, and a Content-Type naming anything else is 415). A request with a body also names it as Content-Type.

REST: create an application, a participant, a topic, write a sample

API=http://127.0.0.1:8080/dds/rest1
ACCEPT='Accept: application/dds-web+xml'
CTYPE='Content-Type: application/dds-web+xml'

# 1. Application
curl -si -X POST "$API/applications" -H "$ACCEPT" -H "$CTYPE" \
  -d '<application><name>app1</name></application>'
# -> 201 Created, Location: applications/app1

# 2. DomainParticipant on domain 0
curl -si -X POST "$API/applications/app1/domain_participants" -H "$ACCEPT" -H "$CTYPE" \
  -d '<domain_participant><domain_id>0</domain_id></domain_participant>'
# -> 201 Created, Location: .../domain_participants/p1

# 3. Topic, naming a type this daemon's `types:` config resolved
curl -si -X POST "$API/applications/app1/domain_participants/p1/topics" -H "$ACCEPT" -H "$CTYPE" \
  -d '<topic><name>Sensor</name><type_name>Demo::Sensor</type_name></topic>'

# 4. Publisher + DataWriter
curl -si -X POST "$API/applications/app1/domain_participants/p1/publishers" -H "$ACCEPT"
# -> Location: .../publishers/pub1
curl -si -X POST "$API/applications/app1/domain_participants/p1/publishers/pub1/data_writers" -H "$ACCEPT" -H "$CTYPE" \
  -d '<data_writer><topic_name>Sensor</topic_name></data_writer>'
# -> Location: .../data_writers/dw1

# 5. Write a sample — the body is the sample itself, converted through
#    the type's own descriptor (crate::dynxml), never an opaque guess.
curl -si -X POST "$API/applications/app1/domain_participants/p1/publishers/pub1/data_writers/dw1" -H "$ACCEPT" -H "$CTYPE" \
  -d '<data><sensor_id>7</sensor_id><value>3.5</value></data>'
# -> 200 OK (a write creates no new resource, unlike the POSTs above)

SOAP and WSDL

The SOAP endpoint is /soap; WriteSample/ReadSample carry the same sample XML REST uses. The WSDL lists every DDS-WEB object-model operation plus every operation of every interface in a config-named interfaces: IDL file:

curl -s http://127.0.0.1:8080/wsdl

Security

Reuses the common substrate of the bridge daemons, zerodds-bridge-security (TLS, auth.mode: none|bearer|jwt|mtls, an ACL). The ACL's resource unit is the Application name, not the DDS topic name.

Configuration

Schema: crates/webdds-bridge/src/daemon/config.rs (man 5 zerodds-webdds-bridged.yaml); worked example: packaging/linux/configs/webdds-bridged.yaml.example. Command reference: zerodds-webdds-bridged(1).

Position

  • Layer 5 — bridges/gateways. The caller layer for zerodds-web and zerodds-soap.

zerodds-webdds-bridge

Gateway-Daemon für OMG DDS-WEB 1.0: REST-PSM (zerodds-web) und SOAP-PSM (zerodds-soap) in einem Prozess, auf Grundlage von zerodds-dcps.

Der Gateway-Daemon für OMG Web-Enabled DDS 1.0 (formal/2014-12-01), zerodds-webdds-bridged. Er bedient den REST-PSM (§8.3, zerodds-web) und den SIMPLE-WSDL-SOAP-PSM (§8.4, zerodds-soap) aus einem Prozess auf einem HTTP-Port — zwei Plattform-Mappings desselben WebDDS-Objektmodells (Spec §1.5), gestützt auf die öffentliche typisierte API von zerodds-dcps.

zerodds-web und zerodds-soap sind reine no_std + alloc-Bibliotheken: Routing, Abbildung der Statuscodes, Register der XML-Element-Tags, Codecs für SOAP-Envelope, -Fault und WSDL. Keine der beiden implementiert einen HTTP-Server, ein DdsBackend oder einen Codec für den Body. Diese Crate ist die aufrufende Schicht.

Module

  • gateway::Gateway — impl zerodds_web::bridge::DdsBackend auf der typisierten API von zerodds-dcps; deckt jede Entity-Operation aus §7.4 ab, Schreiben und Lesen von Samples und die WaitSet-Operationen (das Long-Poll WaitSet::get aus §7.4.9).
  • qos_update — macht aus einem eingebetteten <qos> im Body eines PUT oder einem Verweis <qos_profile> die QoS der Ziel-Entity, vereinigt mit ihrer aktuellen QoS.
  • contained_entities — die verschachtelten <publishers>/<subscribers>/<data_writers>/<data_readers>, die der Body eines Create oder Update tragen kann.
  • types_registry::TypeRegistry — löst den Typ eines Topics auf der Leitung aus einer in der Konfiguration genannten .idl-Datei auf oder über TypeLookup-Discovery eines Peers.
  • dynxml — wandelt ein DynamicData-Sample in die XML-Darstellung aus DDS-WEB §8.1 und zurück, gesteuert vom eigenen Deskriptor des Typs.
  • metadata::MetadataStore — Metadaten von Root nach §7.3.1 (CRUD für QosLibrary/QosProfile/Type).
  • wsdl_bridge — baut das SOAP-WSDL aus den Operationen des DDS-WEB-Objektmodells und den Operationen jedes interface aus einer in der Konfiguration genannten IDL.
  • rest_service / soap_service — Verteilung der Anfragen.
  • http1 — eine selbst geschriebene HTTP/1.1-Engine; keine Abhängigkeit von einem Framework.
  • daemon — Konfiguration, CLI, Sicherheit und Server, in derselben Form wie jeder andere zerodds-*-bridged-Daemon.

Schnellstart

zerodds-webdds-bridged --config /etc/zerodds/webdds-bridged.yaml

oder, für einen schnellen lokalen Lauf ohne Konfigurationsdatei:

zerodds-webdds-bridged --listen 127.0.0.1:8080 --domain 0 \
  --type 'Demo::Sensor=/path/to/sensor.idl'

Jede REST-Anfrage braucht Accept: application/dds-web+xml (Spec §8.3.5 Tab. 7 — die einzige Darstellung, die dieses Gateway ausliefert; ein fehlendes Accept ergibt 400, eines ohne ausgelieferte Darstellung 406, und ein Content-Type mit etwas anderem 415). Eine Anfrage mit Body nennt ihn zusätzlich als Content-Type.

REST: Application, Participant und Topic anlegen, ein Sample schreiben

API=http://127.0.0.1:8080/dds/rest1
ACCEPT='Accept: application/dds-web+xml'
CTYPE='Content-Type: application/dds-web+xml'

# 1. Application
curl -si -X POST "$API/applications" -H "$ACCEPT" -H "$CTYPE" \
  -d '<application><name>app1</name></application>'
# -> 201 Created, Location: applications/app1

# 2. DomainParticipant on domain 0
curl -si -X POST "$API/applications/app1/domain_participants" -H "$ACCEPT" -H "$CTYPE" \
  -d '<domain_participant><domain_id>0</domain_id></domain_participant>'
# -> 201 Created, Location: .../domain_participants/p1

# 3. Topic, naming a type this daemon's `types:` config resolved
curl -si -X POST "$API/applications/app1/domain_participants/p1/topics" -H "$ACCEPT" -H "$CTYPE" \
  -d '<topic><name>Sensor</name><type_name>Demo::Sensor</type_name></topic>'

# 4. Publisher + DataWriter
curl -si -X POST "$API/applications/app1/domain_participants/p1/publishers" -H "$ACCEPT"
# -> Location: .../publishers/pub1
curl -si -X POST "$API/applications/app1/domain_participants/p1/publishers/pub1/data_writers" -H "$ACCEPT" -H "$CTYPE" \
  -d '<data_writer><topic_name>Sensor</topic_name></data_writer>'
# -> Location: .../data_writers/dw1

# 5. Write a sample — the body is the sample itself, converted through
#    the type's own descriptor (crate::dynxml), never an opaque guess.
curl -si -X POST "$API/applications/app1/domain_participants/p1/publishers/pub1/data_writers/dw1" -H "$ACCEPT" -H "$CTYPE" \
  -d '<data><sensor_id>7</sensor_id><value>3.5</value></data>'
# -> 200 OK (a write creates no new resource, unlike the POSTs above)

SOAP und WSDL

Der SOAP-Endpunkt ist /soap; WriteSample/ReadSample tragen dasselbe Sample-XML wie REST. Das WSDL listet jede Operation des DDS-WEB-Objektmodells und jede Operation jedes interface aus einer IDL-Datei, die unter interfaces: in der Konfiguration steht:

curl -s http://127.0.0.1:8080/wsdl

Sicherheit

Nutzt die gemeinsame Grundlage der Bridge-Daemons, zerodds-bridge-security (TLS, auth.mode: none|bearer|jwt|mtls, eine ACL). Die Ressourceneinheit der ACL ist der Name der Application, nicht der Name des DDS-Topics.

Konfiguration

Schema: crates/webdds-bridge/src/daemon/config.rs (man 5 zerodds-webdds-bridged.yaml); ausgearbeitetes Beispiel: packaging/linux/configs/webdds-bridged.yaml.example. Befehlsreferenz: zerodds-webdds-bridged(1).

Stellung

  • Layer 5 — Bridges/Gateways. Die aufrufende Schicht für zerodds-web und zerodds-soap.