From 3b47774d89796c0cdce0b850a82b75dbcfeab590 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Mon, 22 Jun 2026 17:12:24 +0200 Subject: [PATCH 01/10] Update examples and docs Signed-off-by: David Laseca Perez --- docs/conf.py | 6 + docs/resources/examples/change_domain.yaml | 16 --- .../examples/change_domain_allowlist.yaml | 55 --------- docs/resources/examples/echo.yaml | 62 ---------- .../resources/examples/forwarding_routes.yaml | 107 ------------------ docs/resources/examples/repeater_client.yaml | 60 ---------- docs/resources/examples/repeater_server.yaml | 49 -------- .../examples/ros_discovery_client.yaml | 74 ------------ .../examples/ros_discovery_server.yaml | 72 ------------ docs/resources/examples/wan_client.yaml | 84 -------------- docs/resources/examples/wan_ds_client.yaml | 84 -------------- docs/resources/examples/wan_ds_server.yaml | 73 ------------ docs/resources/examples/wan_server.yaml | 73 ------------ docs/resources/examples/xml.yaml | 71 ------------ .../examples/ros_discovery_client.yaml | 1 - .../configurations/examples/wan_client.yaml | 4 +- .../examples/wan_ds_client.yaml | 16 ++- .../examples/wan_ds_server.yaml | 10 +- .../configurations/examples/wan_server.yaml | 21 ++-- 19 files changed, 38 insertions(+), 900 deletions(-) delete mode 100644 docs/resources/examples/change_domain.yaml delete mode 100644 docs/resources/examples/change_domain_allowlist.yaml delete mode 100644 docs/resources/examples/echo.yaml delete mode 100644 docs/resources/examples/forwarding_routes.yaml delete mode 100644 docs/resources/examples/repeater_client.yaml delete mode 100644 docs/resources/examples/repeater_server.yaml delete mode 100644 docs/resources/examples/ros_discovery_client.yaml delete mode 100644 docs/resources/examples/ros_discovery_server.yaml delete mode 100644 docs/resources/examples/wan_client.yaml delete mode 100644 docs/resources/examples/wan_ds_client.yaml delete mode 100644 docs/resources/examples/wan_ds_server.yaml delete mode 100644 docs/resources/examples/wan_server.yaml delete mode 100644 docs/resources/examples/xml.yaml diff --git a/docs/conf.py b/docs/conf.py index 41edf9138..24cbe1f04 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,7 +23,13 @@ import pathlib import re import requests +import shutil +shutil.copytree( + os.path.join(os.path.dirname(__file__), '..', 'resources', 'configurations', 'examples'), + os.path.join(os.path.dirname(__file__), 'resources', 'examples'), + dirs_exist_ok=True +) PROJECT_NAME = 'DDS Router' COMPRESS_PROJECT_NAME = 'ddsrouter' diff --git a/docs/resources/examples/change_domain.yaml b/docs/resources/examples/change_domain.yaml deleted file mode 100644 index a5f2e05c4..000000000 --- a/docs/resources/examples/change_domain.yaml +++ /dev/null @@ -1,16 +0,0 @@ -############################# -# CHANGE DDS DOMAIN EXAMPLE # -############################# - -# DDS Router participants -participants: - - # DDS Simple Participant for DDS Domain 0 - - name: SimpleParticipant_Domain_0 - kind: local - domain: 0 - - # DDS Simple Participant for DDS Domain 1 - - name: SimpleParticipant_Domain_1 - kind: local - domain: 1 diff --git a/docs/resources/examples/change_domain_allowlist.yaml b/docs/resources/examples/change_domain_allowlist.yaml deleted file mode 100644 index 6fc1a0ddb..000000000 --- a/docs/resources/examples/change_domain_allowlist.yaml +++ /dev/null @@ -1,55 +0,0 @@ -######################################## -# CHANGE DOMAIN WITH ALLOWLIST EXAMPLE # -######################################## - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT DOMAIN 0 -# This participant subscribes to allowlist topics in DDS Domain 0 and listen every message published in such DDS Domain - - - name: SimpleParticipant_domain0 # 3 - kind: local # 4 - domain: 0 # 5 - -################################## -# SIMPLE PARTICIPANT DOMAIN 1 -# This participant subscribes to allowlist topics in DDS Domain 1 and listen every message published in such DDS Domain - - - name: SimpleParticipant_domain1 # 6 - kind: local # 7 - domain: 1 # 8 - - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in two different domains -# and transmit those messages through the other domain. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route to them. - -# 3: New Participant with name . - -# 4: Kind of SimpleParticipant_domain0: . -# LAN UDP communication with default simple multicast discovery. - -# 5: SimpleParticipant_domain0 will use DDS Domain ID <0>. - -# 6: New Participant with name . - -# 7: Kind of SimpleParticipant_domain1: . - -# 8: SimpleParticipant_domain1 will use DDS Domain ID <1>. diff --git a/docs/resources/examples/echo.yaml b/docs/resources/examples/echo.yaml deleted file mode 100644 index 2cc1e5e6a..000000000 --- a/docs/resources/examples/echo.yaml +++ /dev/null @@ -1,62 +0,0 @@ -################ -# ECHO EXAMPLE # -################ - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in specific domain and listen every message published there - - - name: SimpleParticipant # 3 - kind: local # 4 - domain: 0 # 5 - -################################## -# ECHO PARTICIPANT -# This Participant will print in stdout every message received by the other Participants, as well as discovery information - - - name: EchoParticipant # 6 - kind: echo # 7 - discovery: true # 8 - data: true # 9 - verbose: true # 10 - - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to print the received -# messages in stdout. Information regarding discovery events is also printed to stdout. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route them. - -# 3: New Participant with name . - -# 4: Kind of SimpleParticipant: . -# LAN UDP communication with default simple multicast discovery. - -# 5: SimpleParticipant will use DDS Domain ID <0>. - -# 6: New Participant with name . - -# 7: Kind of EchoParticipant: . - -# 8: Print a trace to stdout every time an Endpoint is discovered. - -# 9: Print a trace to stdout every time a new data message arrives to the router. - -# 10: Display verbose information regarding received messages (receiver endpoint_guid and data payload). diff --git a/docs/resources/examples/forwarding_routes.yaml b/docs/resources/examples/forwarding_routes.yaml deleted file mode 100644 index 02e38fe2d..000000000 --- a/docs/resources/examples/forwarding_routes.yaml +++ /dev/null @@ -1,107 +0,0 @@ -###################### -# FORWARDING ROUTES # -###################### - -############## -# PARTICIPANTS -participants: # 1 - -#################### -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in domain 0. - - - name: SimpleParticipant_0 # 2 - kind: local # 3 - domain: 0 # 4 - -#################### -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in domain 1. - - - name: SimpleParticipant_1 - kind: local - domain: 1 - - -################ -# GENERIC ROUTES -routes: # 5 - -####### -# ROUTE -# This participant will forward the data it receives to -# SimpleParticipant_1 - - src: SimpleParticipant_0 # 6 - dst: # 7 - - SimpleParticipant_1 # 8 - -####### -# ROUTE -# This participant will not forward the data it receives. - - src: SimpleParticipant_1 # 10 - - -############## -# TOPIC ROUTES -topic-routes: # 11 - - - name: Circle # 12 - type: Configuration # 13 - - routes: # 14 - -############# -# TOPIC ROUTE -# This participant will forward the data it receives on -# topic Circle to SimpleParticipant_0. - - src: SimpleParticipant_1 # 15 - dst: # 16 - - SimpleParticipant_0 # 17 - -############# -# TOPIC ROUTE -# This participant will not forward the data it receives -# on topic Circle. - - src: SimpleParticipant_0 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# to DDS Domain 1. -# The communication is in both directions. - -# 1: List the internal participants of the router. - -# 2: New Participant with name . - -# 3: Kind of SimpleParticipant_0: . -# LAN UDP communication with default simple multicast discovery. - -# 4: SimpleParticipant_0 will use DDS Domain ID <0>. - -# 5: List the generic forwarding routes between the router's internal participants. - -# 6: New forwarding route for SimpleParticipant_0. - -# 7: List the participants SimpleParticipant_0 will forward messages to. - -# 8: SimpleParticipant_0 will forward messages to SimpleParticipant_1. - -# 10: New forwarding route for SimpleParticipant_0. -# Since it doesn't have a dst tag, it will not forward messages to any participant. - -# 11: List the topic forwarding routes between the router's internal participants. - -# 12: New topic forwarding route for topic Circle. - -# 13: The type of the topic Circle for this topic forwarding route to apply must be ShapeType. - -# 14: List the topic forwarding route for topic Circle. - -# 15: New topic forwarding route for SimpleParticipant_0 on topic Circle. - -# 16: List the participants SimpleParticipant_1 will forward messages to on topic Circle. - -# 17: SimpleParticipant_1 will forward messages to SimpleParticipant_0 on topic Circle. diff --git a/docs/resources/examples/repeater_client.yaml b/docs/resources/examples/repeater_client.yaml deleted file mode 100644 index 5196da660..000000000 --- a/docs/resources/examples/repeater_client.yaml +++ /dev/null @@ -1,60 +0,0 @@ -########################### -# REPEATER CLIENT EXAMPLE # -########################### - -################################## -# ALLOWED TOPICS -# Allowing ROS2 HelloWorld demo_nodes - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 0 and listen every message published there - - - name: SimpleROS2 # 2 - kind: local # 3 - domain: 0 # 4 - -################################## -# WAN CLIENT -# This participant will subscribe to topics in allowlist using Initial Peers Participant - - - name: Client # 5 - kind: wan # 6 - connection-addresses: - - domain: "server.domain.com" - port: 11666 - transport: tcp - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topic -# rt/chatter from ROS2 demo_nodes, and to transmit these messages through a WAN Participant (configured as Client) -# to another DDS Router (this configuration is independent of the remote Participant being repeater or not). -# The other direction of communication is also possible; receive messages at the WAN Participant and locally -# publish them in domain 0. - -# 1: Allow ROS 2 specific Topic Name with type . -# Insert new topics in order to route them. - -# 2: New Participant with name . - -# 3: Kind of SimpleROS2: . -# LAN UDP communication with default simple multicast discovery. -# Remember that every ROS 2 Node relays the middleware communication to DDS, as a standard Participant. - -# 4: SimpleROS2 will use DDS Domain ID <0>. - -# 5: New Participant with name . - -# 6: Kind of Client: . - -# 7: Add the configuration to connect with the WAN Repeater Participant raised in the other side. diff --git a/docs/resources/examples/repeater_server.yaml b/docs/resources/examples/repeater_server.yaml deleted file mode 100644 index 15eb9af9a..000000000 --- a/docs/resources/examples/repeater_server.yaml +++ /dev/null @@ -1,49 +0,0 @@ -########################### -# REPEATER SERVER EXAMPLE # -########################### - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# WAN SERVER REPEATER -# This participant will repeat the messages that arrive to it. - - - name: RepeaterParticipant # 3 - kind: wan # 4 - repeater: true # 5 - listening-addresses: - - domain: "server.domain.com" - port: 11666 - transport: tcp - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# through a WAN Participant (configured as Server) to another WAN Participant. -# The other direction of communication is also possible; receive messages at the WAN Participant and locally -# publish them in domain 0. -# Server specifies which DDS Router starts the communication with the other, and after communication has been -# established, both routers behave in the same way. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route them. - -# 3: New Participant with name . - -# 4: Kind of RepeaterParticipant: . -# WAN communication with other DDS Routers. - -# 5: RepeaterParticipant will repeat messages that arrive to it to the rest of DDS Routers connected. diff --git a/docs/resources/examples/ros_discovery_client.yaml b/docs/resources/examples/ros_discovery_client.yaml deleted file mode 100644 index f50ea6fd4..000000000 --- a/docs/resources/examples/ros_discovery_client.yaml +++ /dev/null @@ -1,74 +0,0 @@ -####################################### -# ROS DISCOVERY SERVER CLIENT EXAMPLE # -####################################### - -################################## -# ALLOWED TOPICS -# Allowing ROS2 HelloWorld demo_nodes - -allowlist: - - name: rt/chatter # 1 - type: std_msgs::msg::dds_::String_ # 1 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 0 and listen every message published there - - - name: SimpleROS2 # 2 - kind: local # 3 - domain: 0 # 4 - -################################## -# ROS DISCOVERY CLIENT -# This participant will subscribe to topics in allowlist using Discovery Server protocol as Super Client - - - name: ClientROS2 # 5 - kind: local-discovery-server # 6 - connection-addresses: # 7 - - domain: localhost # 8 - port: 11888 # 9 - # 10 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topic -# rt/chatter from ROS2 demo_nodes, and to transmit these messages through a Discovery Server (configured as -# Super Client) to another Discovery Server (configured as Server). -# The other direction of communication is also possible; receive messages at the Discovery Server and locally -# publish them in domain 0. - -# 1: Allow ROS 2 specific Topic Name with type . -# Insert new topics in order to route them. - -# 2: New Participant with name . - -# 3: Kind of SimpleROS2: . -# LAN UDP communication with default simple multicast discovery. -# Remember that every ROS 2 Node relays the middleware communication to DDS, as a standard Participant. - -# 4: SimpleROS2 will use DDS Domain ID <0>. - -# 5: New Participant with name . - -# 6: Kind of ClientROS2: . -# If not listening address are set for this Participant, it acts as SuperClient of Discovery Server Discovery Protocol. - -# 7: Use the default Discovery Server ROS 2 GuidPrefix <44.53. .5f.45.50.52.4f.53.49.4d.41>. - -# 8: Set this Discovery Server GuidPrefix to <44.53.02.5f.45.50.52.4f.53.49.4d.41>. - -# 9: Add the addresses where this Client will try to reach a Discovery Server. - -# 10: Connect to a Discovery Server in IP localhost listening. This domain will be translated as ip: "127.0.0.1" - -# 11: Discovery Server listening port is 11888. - -# 12: This is the same configuration as the result using Fast DDS environment variable: -# $> export ROS_DISCOVERY_SERVER=";127.0.0.1:11888" -# Add every other address where trying to reach this same remote Discovery Server, -# or add every other Discovery Server connection required. diff --git a/docs/resources/examples/ros_discovery_server.yaml b/docs/resources/examples/ros_discovery_server.yaml deleted file mode 100644 index 57b8db5da..000000000 --- a/docs/resources/examples/ros_discovery_server.yaml +++ /dev/null @@ -1,72 +0,0 @@ -################################ -# ROS DISCOVERY SERVER EXAMPLE # -################################ - -################################## -# ALLOWED TOPICS -# Allowing ROS2 HelloWorld demo_nodes topic - -allowlist: - - name: rt/chatter # 1 - type: std_msgs::msg::dds_::String_ # 1 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 0 and listen every message published there - - - name: SimpleROS2 # 2 - kind: local # 3 - domain: 0 # 4 - -################################## -# ROS DISCOVERY SERVER -# This participant will subscribe to topics in allowlist using Discovery Server protocol as Server - - - name: ServerROS2 # 5 - kind: local-discovery-server # 6 - listening-addresses: # 7 - - domain: localhost # 8 - port: 11888 # 9 - # 10 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topic -# rt/chatter from ROS2 demo_nodes, and to transmit these messages through a Discovery Server (configured as -# Server) to another Discovery Server. -# The other direction of communication is also possible; receive messages at the Discovery Server and locally -# publish them in domain 0. - -# 1: Allow DDS ROS 2 specific Topic Name with type . -# Insert new topics in order to route them. - -# 2: New Participant with name . - -# 3: Kind of SimpleROS2: . -# LAN UDP communication with default simple multicast discovery. -# Remember that every ROS 2 Node relays the middleware communication to DDS, as a standard Participant. - -# 5: New Participant with name . - -# 6: Kind of ServerROS2: . -# This kind of Participant uses Discovery Server as discovery protocol. - -# 7: Use the default Discovery Server ROS 2 GuidPrefix <44.53. .5f.45.50.52.4f.53.49.4d.41> for ServerROS2. - -# 8: Set this Discovery Server GuidPrefix to <44.53.01.5f.45.50.52.4f.53.49.4d.41> for ServerROS2. - -# 9: Add the interfaces where this Discovery Server will listen for client discovery traffic. - -# 10: Listen in IP localhost(127.0.0.1) for remote discovery traffic -# This IP must be set to the IP of the host where this DDS Router will run. - -# 11: Listen in port 11888 - -# 12: This configuration is equal to create a Discovery Server with Fast DDS CLI using command: -# $> fastdds discovery --server-id 1 --ip-address 127.0.0.1 --port 11888 -# Add every other address where this Discovery Server will listen. diff --git a/docs/resources/examples/wan_client.yaml b/docs/resources/examples/wan_client.yaml deleted file mode 100644 index 344c140f7..000000000 --- a/docs/resources/examples/wan_client.yaml +++ /dev/null @@ -1,84 +0,0 @@ -###################### -# WAN CLIENT EXAMPLE # -###################### - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 1 and listen every message published there - - - name: SimpleParticipant # 3 - kind: local # 4 - domain: 1 # 5 - -################################## -# WAN CLIENT -# This participant will subscribe to topics in allowlist and connect with the server through Initial Peers. - - - name: WANClient # 6 - kind: wan # 7 - connection-addresses: # 8 - - ip: 1.1.1.1 # 9 - port: 11666 - listening-addresses: # 10 - - ip: 2.2.2.2 # 11 - port: 11670 # 12 - transport: udp # 13 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 1 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# through a WAN Participant (configured as Client) to another WAN Participant. -# The other direction of communication is also possible; receive messages at the WAN Participant and locally -# publish them in domain 1. -# Client specifies which DDS Router starts the communication with the other, and after communication has been -# established, both routers behave in the same way. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route them. - -# 3: New Participant with name . - -# 4: Kind of SimpleParticipant: . -# LAN UDP communication with default simple multicast discovery. - -# 5: SimpleParticipant will use DDS Domain ID <1>. - -# 6: New Participant with name . - -# 7: Kind of WANClient: . -# WAN communication with another DDS Router. - -# 8: Add the addresses where to reach the remote DDS Routers that will connect to. -# Add as many connection-addresses as needed. - -# 9: Connect to a WAN Participant in IP <1.1.1.1> listening in port 11666 over UDP transport (default). -# This is the same configuration that must be set in the DDS Router that works as a Server in its listening-addresses. -# Add every other address where trying to reach this same remote WAN Server. - -# 10: Add the interfaces where this Participant will listen in WAN. -# This is only needed if Remote WAN Server is using only UDP. -# Add as many listening-addresses as needed. - -# 11: Listen in public IP (2.2.2.2) for remote traffic. -# This IP must be set to the public IP of the host where this DDS Router will run. - -# 12: Listening port is 11670. -# Remember that if the host is under a NAT, the IP must be the public one and must be forwarded from network -# router to this host to the same port. - -# 13: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". diff --git a/docs/resources/examples/wan_ds_client.yaml b/docs/resources/examples/wan_ds_client.yaml deleted file mode 100644 index 27192244f..000000000 --- a/docs/resources/examples/wan_ds_client.yaml +++ /dev/null @@ -1,84 +0,0 @@ -####################################### -# WAN DISCOVERY SERVER CLIENT EXAMPLE # -####################################### - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 1 and listen every message published there - - - name: SimpleParticipant # 3 - kind: local # 4 - domain: 1 # 5 - -################################## -# WAN CLIENT -# This participant will subscribe to topics in allowlist using Discovery Server protocol as SuperClient. - - - name: WANClient # 6 - kind: wan-ds # 7 - connection-addresses: # 8 - - ip: 1.1.1.1 # 9 - port: 11666 - listening-addresses: # 10 - - ip: 2.2.2.2 # 11 - port: 11670 # 12 - transport: udp # 13 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 1 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# through a Discovery Server WAN Participant (configured as Super Client) to another Discovery Server WAN Participant. -# The other direction of communication is also possible; receive messages at the Discovery Server WAN Participant and locally -# publish them in domain 1. -# Client specifies which DDS Router starts the communication with the other, and after communication has been -# established, both routers behave in the same way. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route them. - -# 3: New Participant with name . - -# 4: Kind of SimpleParticipant: . -# LAN UDP communication with default simple multicast discovery. - -# 5: SimpleParticipant will use DDS Domain ID <1>. - -# 6: New Participant with name . - -# 7: Kind of WANClient: . -# WAN communication with another DDS Router via Discovery Server. - -# 8: Add the addresses where to reach the remote DDS Routers that will connect to. -# Add as many connection-addresses as needed. - -# 9: Connect to a Discovery Server in IP <1.1.1.1> listening in port 11666 over UDP transport (default). -# This is the same configuration that must be set in the DDS Router that works as a Server in its listening-addresses. -# Add every other address where trying to reach this same remote WAN Discovery Server. - -# 10: Add the interfaces where this Participant will listen in WAN. -# This is only needed if Remote WAN Server is using only UDP. -# Add as many listening-addresses as needed. - -# 11: Listen in public IP (2.2.2.2) for remote traffic. -# This IP must be set to the public IP of the host where this DDS Router will run. - -# 12: Listening port is 11670. -# Remember that if the host is under a NAT, the IP must be the public one and must be forwarded from network -# router to this host to the same port. - -# 13: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". diff --git a/docs/resources/examples/wan_ds_server.yaml b/docs/resources/examples/wan_ds_server.yaml deleted file mode 100644 index 79316633a..000000000 --- a/docs/resources/examples/wan_ds_server.yaml +++ /dev/null @@ -1,73 +0,0 @@ -####################################### -# WAN DISCOVERY SERVER SERVER EXAMPLE # -####################################### - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 0 and listen every message published there - - - name: SimpleParticipant # 3 - kind: local # 4 - domain: 0 # 5 - -################################## -# WAN SERVER -# This participant will subscribe to topics in allowlist using Discovery Server protocol as Server - - - name: WANServer # 6 - kind: wan-ds # 7 - listening-addresses: # 8 - - ip: 1.1.1.1 # 9 - port: 11666 # 10 - transport: udp # 11 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# through a Discovery Server WAN Participant (configured as Server) to another Discovery Server WAN Participant. -# The other direction of communication is also possible; receive messages at the Discovery Server WAN Participant -# and locally publish them in domain 0. -# Server specifies which DDS Router starts the communication with the other, and after communication has been -# established, both routers behave in the same way. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route them. - -# 3: New Participant with name . - -# 4: Kind of SimpleParticipant: . -# LAN UDP communication with default simple multicast discovery. - -# 5: SimpleParticipant will use DDS Domain ID <0>. - -# 6: New Participant with name . - -# 7: Kind of WANServer: . -# WAN communication with another DDS Router via Discovery Server. - -# 8: Add the interfaces where this Participant will listen in WAN. -# Add as many listening-addresses as needed. - -# 9: Listen in public IP (1.1.1.1) for remote traffic. -# This IP must be set to the public IP of the host where this DDS Router will run. - -# 10: Listening port is 11666. -# Remember that if the host is under a NAT, the IP must be the public one and must be forwarded from network -# router to this host to the same port. - -# 11: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". diff --git a/docs/resources/examples/wan_server.yaml b/docs/resources/examples/wan_server.yaml deleted file mode 100644 index 02c2bce14..000000000 --- a/docs/resources/examples/wan_server.yaml +++ /dev/null @@ -1,73 +0,0 @@ -###################### -# WAN SERVER EXAMPLE # -###################### - -################################## -# ALLOWED TOPICS -# Allowing FastDDS and ROS2 HelloWorld demo examples topics - -allowlist: - - name: HelloWorldTopic # 1 - - name: rt/chatter # 2 - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 0 and listen every message published there - - - name: SimpleParticipant # 3 - kind: local # 4 - domain: 0 # 5 - -################################## -# WAN SERVER -# This participant will subscribe to topics in allowlist and connect to clients through Initial Peers. - - - name: WANServer # 6 - kind: wan # 7 - listening-addresses: # 8 - - ip: 1.1.1.1 # 9 - port: 11666 # 10 - transport: udp # 11 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# through a WAN Participant (configured as Server) to another WAN Participant. -# The other direction of communication is also possible; receive messages at the WAN Participant and locally -# publish them in domain 0. -# Server specifies which DDS Router starts the communication with the other, and after communication has been -# established, both routers behave in the same way. - -# 1: Allow DDS Topic Name with type . - -# 2: Insert new topics in order to route them. - -# 3: New Participant with name . - -# 4: Kind of SimpleParticipant: . -# LAN UDP communication with default simple multicast discovery. - -# 5: SimpleParticipant will use DDS Domain ID <0>. - -# 6: New Participant with name . - -# 7: Kind of WANServer: . -# WAN communication with another DDS Router. - -# 8: Add the interfaces where this Participant will listen in WAN. -# Add as many listening-addresses as needed. - -# 9: Listen in public IP (1.1.1.1) for remote traffic. -# This IP must be set to the public IP of the host where this DDS Router will run. - -# 10: Listening port is 11666. -# Remember that if the host is under a NAT, the IP must be the public one and must be forwarded from network -# router to this host to the same port. - -# 11: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". diff --git a/docs/resources/examples/xml.yaml b/docs/resources/examples/xml.yaml deleted file mode 100644 index 12a6c4be9..000000000 --- a/docs/resources/examples/xml.yaml +++ /dev/null @@ -1,71 +0,0 @@ -###################### -# XML EXAMPLE # -###################### - -################################## -# XML CONFIGURATION -xml: # 1 - files: - - "./xml_configuration.xml" # 2 - raw: | # 3 - - - - 1 - - - - -################################## -# PARTICIPANTS -participants: - -################################## -# SIMPLE PARTICIPANT -# This participant will subscribe to topics in allowlist in domain 0 and listen every message published there - - - name: SimpleParticipant # 6 - kind: local # 7 - domain: 0 # 8 - -################################## -# WAN SERVER -# This participant will subscribe to topics in allowlist and connect to clients through Initial Peers. - - - name: XMLParticipant # 9 - kind: xml # 10 - profile: custom_participant_configuration # 11 - -################################## -# CONFIGURATION DESCRIPTION - -# This configuration example configures a DDS Router to listen to every message published in domain 0 in topics -# HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages -# to DDS Domain 1. -# The communication is in both directions. - -# 1: Configure how to load XML configurations. - -# 2: Load profiles from every xml file in list. - -# 3: Read the next string as XML and load profiles from it. - -# 4: Allow DDS Topic Name with type . - -# 5: Insert new topics in order to route them. - -# 6: New Participant with name . - -# 7: Kind of SimpleParticipant: . -# LAN UDP communication with default simple multicast discovery. - -# 8: SimpleParticipant will use DDS Domain ID <0>. - -# 9: New Participant with name . - -# 10: Kind of XMLParticipant: . -# XML configuration - -# 11: Profile QoS to create Participant is custom_participant_configuration -# This participant will be configured following such profile QoS. -# In this case, the profile only configures the domain to be 1 diff --git a/resources/configurations/examples/ros_discovery_client.yaml b/resources/configurations/examples/ros_discovery_client.yaml index 5df28d604..f50ea6fd4 100644 --- a/resources/configurations/examples/ros_discovery_client.yaml +++ b/resources/configurations/examples/ros_discovery_client.yaml @@ -28,7 +28,6 @@ participants: - name: ClientROS2 # 5 kind: local-discovery-server # 6 - connection-addresses: # 7 - domain: localhost # 8 port: 11888 # 9 diff --git a/resources/configurations/examples/wan_client.yaml b/resources/configurations/examples/wan_client.yaml index 4dd908b8e..4820e05e8 100644 --- a/resources/configurations/examples/wan_client.yaml +++ b/resources/configurations/examples/wan_client.yaml @@ -26,7 +26,7 @@ participants: # INITIAL PEERS CLIENT # This participant will subscribe to topics in allowlist using Initial Peers Discovery protocol connecting to remote. - - name: WanParticipant # 6 + - name: WanClient # 6 kind: wan # 7 connection-addresses: # 8 - ip: 1.1.1.1 @@ -59,7 +59,7 @@ participants: # 5: SimpleParticipant will use DDS Domain ID <1>. -# 6: New Participant with name . +# 6: New Participant with name . # 7: Kind of WANClient: . # InitialPeers discovery to discover and communicate with another Initial Peers participant. diff --git a/resources/configurations/examples/wan_ds_client.yaml b/resources/configurations/examples/wan_ds_client.yaml index 49bb88bb4..2873f68e7 100644 --- a/resources/configurations/examples/wan_ds_client.yaml +++ b/resources/configurations/examples/wan_ds_client.yaml @@ -35,6 +35,7 @@ participants: - ip: 2.2.2.2 # 11 port: 11670 # 12 transport: udp # 13 + ################################## # CONFIGURATION DESCRIPTION @@ -65,6 +66,19 @@ participants: # 8: Add the addresses where to reach the remote DDS Routers that will connect to. # Add as many connection-addresses as needed. -# 9: Connect to a Discovery Server in IP <1.1.1.1> listening in port 11777 over TCP transport. +# 9: Connect to a Discovery Server in IP <1.1.1.1> listening in port 11666 over UDP transport (default). # This is the same configuration that must be set in the DDS Router that works as a Server in its listening-addresses. # Add every other address where trying to reach this same remote WAN Discovery Server. + +# 10: Add the interfaces where this Participant will listen in WAN. +# This is only needed if Remote WAN Server is using only UDP. +# Add as many listening-addresses as needed. + +# 11: Listen in public IP (2.2.2.2) for remote traffic. +# This IP must be set to the public IP of the host where this DDS Router will run. + +# 12: Listening port is 11670. +# Remember that if the host is under a NAT, the IP must be the public one and must be forwarded from network +# router to this host to the same port. + +# 13: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". diff --git a/resources/configurations/examples/wan_ds_server.yaml b/resources/configurations/examples/wan_ds_server.yaml index 4287599d1..02876cf52 100644 --- a/resources/configurations/examples/wan_ds_server.yaml +++ b/resources/configurations/examples/wan_ds_server.yaml @@ -39,8 +39,8 @@ participants: # This configuration example configures a DDS Router to listen to every message published in domain 0 in topics # HelloWorldTopic (from Fast DDS HelloWorld) and rt/chatter from ROS2 demo_nodes, and to transmit these messages # through a Discovery Server WAN Participant (configured as Server) to another Discovery Server WAN Participant. -# The other direction of communication is also possible; receive messages at the Discovery Server WAN Participant and locally -# publish them in domain 0. +# The other direction of communication is also possible; receive messages at the Discovery Server WAN Participant +# and locally publish them in domain 0. # Server specifies which DDS Router starts the communication with the other, and after communication has been # established, both routers behave in the same way. @@ -70,8 +70,4 @@ participants: # Remember that if the host is under a NAT, this port is the one that the host will open, but not the one # used as public in the router. -# 11: External port is 11777. -# This port is used in case the host is under a NAT. This is the public port accessible from any external point -# in the network, and should be forwarded from the network router to the "port" value. - -# 12: It uses TCP. UDP transport is used by default if not set. Could be set to "udp" or "tcp". +# 11: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". diff --git a/resources/configurations/examples/wan_server.yaml b/resources/configurations/examples/wan_server.yaml index 565f19061..6d163f2a7 100644 --- a/resources/configurations/examples/wan_server.yaml +++ b/resources/configurations/examples/wan_server.yaml @@ -26,12 +26,12 @@ participants: # WAN SERVER # This participant will subscribe to topics in allowlist using Initial Peers Discovery protocol awaiting connections. - - name: WanParticipant # 6 + - name: WanServer # 6 kind: wan # 7 - listening-addresses: - - ip: 1.1.1.1 # 8 - port: 11666 # 9 - transport: udp # 10 + listening-addresses: # 8 + - ip: 1.1.1.1 # 9 + port: 11666 # 10 + transport: udp # 11 ################################## # CONFIGURATION DESCRIPTION @@ -55,14 +55,17 @@ participants: # 5: SimpleParticipant will use DDS Domain ID <0>. -# 6: New Participant with name . +# 6: New Participant with name . # 7: Kind of WANClient: . # InitialPeers discovery to discover and communicate with another WAN DDS Router. -# 8: Listen in public IP (1.1.1.1) for remote traffic. +# 8: Add the interfaces where this Participant will listen in WAN. +# Add as many listening-addresses as needed. + +# 9: Listen in public IP (1.1.1.1) for remote traffic. # This IP must be set to the public IP of the host where this DDS Router will run. -# 9: Listening port is 11666. +# 10: Listening port is 11666. -# 10: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". +# 11: It uses UDP transport by default if not set. Could be set to "udp" or "tcp". From 6ce2115e5a82b64b2e0e5606fd285f9f62dfb179 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Mon, 22 Jun 2026 17:18:13 +0200 Subject: [PATCH 02/10] Modify .gitignore to prevent duplicating example files Signed-off-by: David Laseca Perez --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e2ebcf1a7..0a429aea5 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ log/ docs/rst/_static/css/eprosima-furo.css docs/rst/_static/eprosima-logo-white.png docs/rst/_templates/sidebar/ +docs/resources/examples/ ### Python ### From 8deae973c6a4e121f8dac72816f8731d269cab47 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Tue, 23 Jun 2026 07:35:14 +0200 Subject: [PATCH 03/10] Adjust documentation Signed-off-by: David Laseca Perez --- docs/rst/examples/wan_example.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rst/examples/wan_example.rst b/docs/rst/examples/wan_example.rst index 34989dfaa..0489f97d0 100644 --- a/docs/rst/examples/wan_example.rst +++ b/docs/rst/examples/wan_example.rst @@ -60,7 +60,7 @@ In order to create a WAN Participant Client, check the configuration file .. literalinclude:: ../../resources/examples/wan_client.yaml :language: yaml - :lines: 29-37 + :lines: 29-38 Execute example From 14d1269c7f7fc18ab3c8f93b7fff5f7e34dc77b7 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Tue, 23 Jun 2026 16:49:16 +0200 Subject: [PATCH 04/10] Clean old python YAML validator Signed-off-by: David Laseca Perez --- .github/docker/ddsrouter/Dockerfile | 4 +- .../installation/sources/linux.rst | 2 - .../installation/sources/windows.rst | 2 - docs/rst/notes/previous_versions/v0.4.0.rst | 2 +- docs/rst/user_manual/yaml_validator.rst | 6 + tools/ddsrouter_yaml_validator/.gitignore | 98 --- .../ddsrouter_yaml_validator/__init__.py | 0 .../ddsrouter_config_schema.json | 679 ------------------ .../ddsrouter_yaml_validator.py | 31 - .../full_example.yaml | 90 --- .../ddsrouter_yaml_validator/parser.py | 54 -- .../ddsrouter_yaml_validator/validator.py | 103 --- tools/ddsrouter_yaml_validator/package.xml | 17 - .../resource/ddsrouter_yaml_validator | 0 tools/ddsrouter_yaml_validator/setup.cfg | 4 - tools/ddsrouter_yaml_validator/setup.py | 31 - .../tests/__init__.py | 0 .../tests/ddsrouter_yaml_validator_test.py | 51 -- .../address_no_ip_nor_domain.yaml | 35 - .../address_no_port.yaml | 36 - .../builtin_topic_no_name.yaml | 14 - .../builtin_topic_no_type.yaml | 14 - ..._participant_no_discovery_server_guid.yaml | 33 - ...no_listening_nor_connection_addresses.yaml | 20 - .../filter_topic_no_name.yaml | 14 - .../initial_peers_no_addresses.yaml | 16 - .../no_participant_kind.yaml | 16 - .../no_participant_name.yaml | 16 - .../no_version.yaml | 15 - .../tls_ca_no_private_key_provided_cert.yaml | 40 -- .../tls_no_ca.yaml | 42 -- 31 files changed, 8 insertions(+), 1477 deletions(-) delete mode 100644 tools/ddsrouter_yaml_validator/.gitignore delete mode 100644 tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/__init__.py delete mode 100644 tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_config_schema.json delete mode 100644 tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_yaml_validator.py delete mode 100644 tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/full_example.yaml delete mode 100644 tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/parser.py delete mode 100644 tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/validator.py delete mode 100644 tools/ddsrouter_yaml_validator/package.xml delete mode 100644 tools/ddsrouter_yaml_validator/resource/ddsrouter_yaml_validator delete mode 100644 tools/ddsrouter_yaml_validator/setup.cfg delete mode 100644 tools/ddsrouter_yaml_validator/setup.py delete mode 100644 tools/ddsrouter_yaml_validator/tests/__init__.py delete mode 100644 tools/ddsrouter_yaml_validator/tests/ddsrouter_yaml_validator_test.py delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_ip_nor_domain.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_port.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_name.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_type.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_discovery_server_guid.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_listening_nor_connection_addresses.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/filter_topic_no_name.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/initial_peers_no_addresses.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_kind.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_name.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_version.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_ca_no_private_key_provided_cert.yaml delete mode 100644 tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_no_ca.yaml diff --git a/.github/docker/ddsrouter/Dockerfile b/.github/docker/ddsrouter/Dockerfile index 544a1d2e6..cd6472a6a 100644 --- a/.github/docker/ddsrouter/Dockerfile +++ b/.github/docker/ddsrouter/Dockerfile @@ -35,9 +35,7 @@ RUN pip3 install \ colcon-mixin \ lxml \ vcstool \ - GitPython \ - pyyaml \ - jsonschema + GitPython WORKDIR /ddsrouter diff --git a/docs/rst/developer_manual/installation/sources/linux.rst b/docs/rst/developer_manual/installation/sources/linux.rst index f85fdc8a1..e5dd55cdc 100644 --- a/docs/rst/developer_manual/installation/sources/linux.rst +++ b/docs/rst/developer_manual/installation/sources/linux.rst @@ -41,8 +41,6 @@ installed in the system: * :ref:`cmake_gcc_pip_wget_git_sl` * :ref:`colcon_install` [optional] * :ref:`gtest_sl` [for test only] -* :ref:`py_yaml` [for YAML Validator only] -* :ref:`json_schema` [for YAML Validator only] .. _cmake_gcc_pip_wget_git_sl: diff --git a/docs/rst/developer_manual/installation/sources/windows.rst b/docs/rst/developer_manual/installation/sources/windows.rst index 5988510c4..09442615e 100644 --- a/docs/rst/developer_manual/installation/sources/windows.rst +++ b/docs/rst/developer_manual/installation/sources/windows.rst @@ -44,8 +44,6 @@ installed in the system: * :ref:`windows_sources_cmake_pip3_wget_git` * :ref:`windows_sources_colcon_install` [optional] * :ref:`windows_sources_gtest` [for test only] -* :ref:`windows_py_yaml` [for YAML Validator only] -* :ref:`windows_json_schema` [for YAML Validator only] .. _windows_sources_visual_studio: diff --git a/docs/rst/notes/previous_versions/v0.4.0.rst b/docs/rst/notes/previous_versions/v0.4.0.rst index 309545ead..97fc992df 100644 --- a/docs/rst/notes/previous_versions/v0.4.0.rst +++ b/docs/rst/notes/previous_versions/v0.4.0.rst @@ -4,7 +4,7 @@ Version v0.4.0 This release includes the following **features**: -* New :ref:`yaml_validator`, a simple tool to assert the correctness of DDS Router configuration files. +* New YAML validator, a simple tool to assert the correctness of DDS Router configuration files. * New :ref:`user_manual_user_interface_version_argument` to show the current version of DDS Router. This release includes the following **improvementes**: diff --git a/docs/rst/user_manual/yaml_validator.rst b/docs/rst/user_manual/yaml_validator.rst index 5134624bb..70580f53e 100644 --- a/docs/rst/user_manual/yaml_validator.rst +++ b/docs/rst/user_manual/yaml_validator.rst @@ -7,6 +7,12 @@ YAML Validator ############## +.. warning:: + + **DEPRECATED** + + This standalone YAML Validator tool is deprecated. + Configuration files used to launch a DDS-Router instance need to follow a specific structure, which is extensively described along section :ref:`user_manual_configuration`. The *YAML Validator tool* has been developed for the sole purpose of validating user-defined configuration files in an easy manner. diff --git a/tools/ddsrouter_yaml_validator/.gitignore b/tools/ddsrouter_yaml_validator/.gitignore deleted file mode 100644 index f42e32aba..000000000 --- a/tools/ddsrouter_yaml_validator/.gitignore +++ /dev/null @@ -1,98 +0,0 @@ - -### C++ ### -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -### Vim ### -# swap -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -# session -Session.vim -# temporary -.netrwhist -*~ -# auto-generated tag files -tags - -build/ -install/ -# Log is commented because some internal modules could be called like that -# log/ - -### Visual Studio ### -.vs - -### Visual Studio Code ### -.vscode - -### Documentation ### -docs/rst/_static/css/online_eprosima_rtd_theme.css - -### Python ### -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST diff --git a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/__init__.py b/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_config_schema.json b/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_config_schema.json deleted file mode 100644 index 46e01806b..000000000 --- a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_config_schema.json +++ /dev/null @@ -1,679 +0,0 @@ -{ - "$schema":"http://json-schema.org/draft-07/schema#", - "$ref":"#/definitions/BaseObject", - "definitions":{ - "BaseObject":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "threads":{ - "type":"integer" - }, - "version":{ - "type":"string", - "enum":[ - "v3.0" - ] - }, - "allowlist":{ - "type":"array", - "items":{ - "$ref":"#/definitions/TopicFilter" - } - }, - "blocklist":{ - "type":"array", - "items":{ - "$ref":"#/definitions/TopicFilter" - } - }, - "builtin-topics":{ - "type":"array", - "items":{ - "$ref":"#/definitions/TopicBuiltins" - } - }, - "participants":{ - "type":"array", - "minItems":1, - "items":{ - "$ref":"#/definitions/Participant" - }, - "uniqueKeys":[ - "/name" - ] - } - }, - "required":[ - "version", - "participants" - ], - "title":"BaseObject" - }, - "TopicFilter":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "name":{ - "type":"string" - }, - "type":{ - "type":"string" - }, - "keyed":{ - "type":"boolean" - } - }, - "required":[ - "name" - ], - "title":"TopicFilter" - }, - "TopicBuiltins":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "name":{ - "type":"string" - }, - "type":{ - "type":"string" - }, - "keyed":{ - "type":"boolean" - }, - "reliable":{ - "type":"boolean" - } - }, - "required":[ - "name", - "type" - ], - "title":"TopicBuiltins" - }, - "Participant":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "name":{ - "type":"string" - }, - "kind":{ - "type":"string", - "enum":[ - "void", - "echo", - "dummy", - "local", - "simple", - "discovery-server", - "ds", - "local-ds", - "local-discovery-server", - "wan-ds", - "wan-discovery-server", - "wan", - "router" - ] - }, - "domain":{ - "type":"integer", - "minimum":0, - "maximum":230 - }, - "repeater":{ - "type":"boolean" - }, - "discovery-server-guid":{ - "$ref":"#/definitions/DiscoveryServerGUID" - }, - "listening-addresses":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Address" - }, - "minItems": 1 - }, - "connection-addresses":{ - "type":"array", - "items":{ - "anyOf":[ - { - "$ref":"#/definitions/DsConnectionAddress" - }, - { - "$ref":"#/definitions/Address" - } - ] - }, - "minItems": 1 - }, - "tls":{ - "$ref":"#/definitions/TLS" - }, - "discovery":{ - "type":"boolean" - }, - "data":{ - "type":"boolean" - }, - "verbose":{ - "type":"boolean" - } - }, - "required":[ - "kind", - "name" - ], - "allOf":[ - { - "if":{ - "properties":{ - "kind":{ - "type":"string", - "enum":[ - "void", - "dummy" - ] - } - } - }, - "then":{ - "properties":{ - "domain":{ - "not":{ - - } - }, - "discovery-server-guid":{ - "not":{ - - } - }, - "listening-addresses":{ - "not":{ - - } - }, - "connection-addresses":{ - "not":{ - - } - }, - "tls":{ - "not":{ - - } - }, - "repeater":{ - "not":{ - - } - }, - "discovery":{ - "not":{ - - } - }, - "data":{ - "not":{ - - } - }, - "verbose":{ - "not":{ - - } - } - } - } - }, - { - "if":{ - "properties":{ - "kind":{ - "type":"string", - "enum":[ - "echo" - ] - } - } - }, - "then":{ - "properties":{ - "domain":{ - "not":{ - - } - }, - "discovery-server-guid":{ - "not":{ - - } - }, - "listening-addresses":{ - "not":{ - - } - }, - "connection-addresses":{ - "not":{ - - } - }, - "tls":{ - "not":{ - - } - }, - "repeater":{ - "not":{ - - } - } - } - } - }, - { - "if":{ - "properties":{ - "kind":{ - "type":"string", - "enum":[ - "local", - "simple" - ] - } - } - }, - "then":{ - "allOf":[ - { - "properties":{ - "discovery-server-guid":{ - "not":{ - - } - }, - "listening-addresses":{ - "not":{ - - } - }, - "connection-addresses":{ - "not":{ - - } - }, - "tls":{ - "not":{ - - } - }, - "repeater":{ - "not":{ - - } - }, - "discovery":{ - "not":{ - - } - }, - "data":{ - "not":{ - - } - }, - "verbose":{ - "not":{ - - } - } - } - } - ] - } - }, - { - "if":{ - "properties":{ - "kind":{ - "type":"string", - "enum":[ - "discovery-server", - "ds", - "local-ds", - "local-discovery-server", - "wan-ds", - "wan-discovery-server" - ] - } - } - }, - "then":{ - "allOf":[ - { - "properties":{ - "domain":{ - "not":{ - - } - }, - "discovery":{ - "not":{ - - } - }, - "data":{ - "not":{ - - } - }, - "verbose":{ - "not":{ - - } - } - } - }, - { - "required":[ - "discovery-server-guid" - ] - }, - { - "anyOf":[ - { - "required":[ - "listening-addresses" - ] - }, - { - "required":[ - "connection-addresses" - ] - } - ] - } - ] - } - }, - { - "if":{ - "properties":{ - "kind":{ - "type":"string", - "enum":[ - "wan", - "router" - ] - } - } - }, - "then":{ - "allOf":[ - { - "properties":{ - "discovery-server-guid":{ - "not":{ - - } - }, - "discovery":{ - "not":{ - - } - }, - "data":{ - "not":{ - - } - }, - "verbose":{ - "not":{ - - } - } - } - }, - { - "anyOf":[ - { - "required":[ - "listening-addresses" - ] - }, - { - "required":[ - "connection-addresses" - ] - } - ] - } - ] - } - } - ], - "title":"Participant" - }, - "DiscoveryServerGUID":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "guid":{ - "type":"string" - }, - "id":{ - "type":"integer" - }, - "ros-discovery-server":{ - "type":"boolean" - } - }, - "anyOf":[ - { - "required":[ - "guid" - ] - }, - { - "required":[ - "id" - ] - } - ], - "title":"DiscoveryServerGUID" - }, - "DsConnectionAddress":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "discovery-server-guid":{ - "$ref":"#/definitions/DiscoveryServerGUID" - }, - "addresses":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Address" - } - } - }, - "required":[ - "addresses", - "discovery-server-guid" - ], - "title":"DsConnectionAddress" - }, - "TLS":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "ca":{ - "type":"string" - }, - "password":{ - "type":"string" - }, - "private_key":{ - "type":"string" - }, - "cert":{ - "type":"string" - }, - "dh_params":{ - "type":"string" - }, - "peer_verification":{ - "type":"boolean" - }, - "sni_host":{ - "type":"string" - } - }, - "required":[ - "ca" - ], - "allOf":[ - { - "if":{ - "properties":{ - "password":{ - "type":"string" - } - }, - "required":[ - "password" - ] - }, - "then":{ - "required":[ - "private_key", - "cert" - ] - } - }, - { - "if":{ - "properties":{ - "private_key":{ - "not":{ - "pattern":"^$" - } - } - }, - "required":[ - "private_key" - ] - }, - "then":{ - "properties":{ - "private_key":{ - "not":{ - "pattern":"^\\s*$" - } - } - }, - "required":[ - "password", - "cert" - ] - } - }, - { - "if":{ - "properties":{ - "cert":{ - "type":"string" - } - }, - "required":[ - "cert" - ] - }, - "then":{ - "properties":{ - "cert":{ - "not":{ - "pattern":"^\\s*$" - } - } - }, - "required":[ - "password", - "private_key" - ] - } - } - ], - "title":"TLS" - }, - "Address":{ - "type":"object", - "additionalProperties":false, - "properties":{ - "ip":{ - "type":"string", - "anyOf":[ - { - "format":"v4" - }, - { - "format":"v6" - } - ] - }, - "domain":{ - "type":"string" - }, - "port":{ - "type":"integer", - "minimum":0, - "maximum":65535 - }, - "external-port":{ - "type":"integer", - "minimum":0, - "maximum":65535 - }, - "transport":{ - "type":"string", - "enum":[ - "tcp", - "udp" - ] - }, - "ip-version":{ - "type":"string", - "enum":[ - "v4", - "v6" - ] - } - }, - "allOf":[ - { - "anyOf":[ - { - "required":[ - "domain" - ] - }, - { - "required":[ - "ip" - ] - } - ] - }, - { - "required":[ - "port" - ] - } - ], - "title":"Address" - } - } -} \ No newline at end of file diff --git a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_yaml_validator.py b/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_yaml_validator.py deleted file mode 100644 index 9e2cadb99..000000000 --- a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/ddsrouter_yaml_validator.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""DDS-Router YAML Validator tool.""" - -from ddsrouter_yaml_validator.parser import Parser -from ddsrouter_yaml_validator.validator import YamlValidator - - -def main(args=None): - """Validate a DDS-Router YAML configuration file.""" - parser = Parser() - args = parser.parse() - - validator = YamlValidator() - validator.validate(args.config_file, args.schema, args.recursive) - - -if __name__ == '__main__': - main() diff --git a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/full_example.yaml b/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/full_example.yaml deleted file mode 100644 index 11554456c..000000000 --- a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/full_example.yaml +++ /dev/null @@ -1,90 +0,0 @@ -version: v5.0 # Required - -threads: 32 # Optional - -allowlist: -- name: rt/chatter # Required - type: std_msgs::msg::dds_::String_ - keyed: true - -blocklist: -- name: rt/chatter # Required - type: std_msgs::msg::dds_::String_ - keyed: true - -builtin-topics: -- name: rt/chatter # Required - type: std_msgs::msg::dds_::String_ # Required - -- name: custom_topic # Required - type: custom_topic_type # Required - -topics: - - name: rt/chatter - qos: - keyed: true - - -participants: -- name: participant0 # Required - kind: echo # Required - -- name: participant1 # Required - kind: simple # Required - domain: 1 - -- name: participant2 - kind: discovery-server - discovery-server-guid: # Required - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe # Required guid or id - id: 0 # Required guid or id - ros-discovery-server: true - listening-addresses: # Required listening-addresses or connection-addresses - - ip: 127.0.0.1 # Required ip or domain - domain: localhost # Required ip or domain - port: 11667 # Required - transport: udp - ip-version: ipv4 - connection-addresses: # Required listening-addresses or connection-addresses - - discovery-server-guid: # Required - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe # Required guid or id - id: 0 # Required guid or id - ros-discovery-server: true - addresses: # Required - - ip: 127.0.0.1 # Required ip or domain - domain: localhost # Required ip or domain - port: 11667 # Required - transport: udp - ip-version: ipv4 - tls: - ca: ca.crt # Required - password: ddsrouterpass # If "password" present, "private_key" and "cert" required - private_key: ddsrouter.key # If "private_key" present, "password" and "cert" required - cert: ddsrouter.crt # If "cert" present, "password" and "private_key" required - dh_params: dh_params.pem - -- name: participant3 - kind: wan - discovery-server-guid: # Required - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe # Required guid or id - id: 0 # Required guid or id - ros-discovery-server: true - listening-addresses: # Required listening-addresses or connection-addresses - - ip: ::1 # Required ip or domain - domain: localhost # Required ip or domain - port: 11667 - transport: tcp - ip-version: ipv6 - connection-addresses: # Required listening-addresses or connection-addresses - - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe # Required guid or id - id: 0 # Required guid or id - ros-discovery-server: true - addresses: - - ip: 127.0.0.1 # Required ip or domain - domain: localhost # Required ip or domain - port: 11667 - transport: tcp - ip-version: ipv4 - tls: - ca: ca.crt # Required diff --git a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/parser.py b/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/parser.py deleted file mode 100644 index 2a7c85063..000000000 --- a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/parser.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Argument parser for DDS-Router YAML Validator tool.""" - -import argparse -import os - - -class Parser: - """DDS-Router YAML Validator argument parser.""" - - def parse(self): - """Parse configuration and schema path arguments.""" - parser = argparse.ArgumentParser( - description='Validate DDS-Router configuration file.' - ) - parser.add_argument( - '-c', - '--config-file', - required=True, - help='YAML file or directory with files used to configure' - 'DDS-Router', - ) - parser.add_argument( - '-r', - '--recursive', - action='store_true', - default=False, - help='Whether to perform recursive search when --config-file' - ' refers to a directory (default: false)', - ) - parser.add_argument( - '-s', - '--schema', - default=os.path.join( - os.environ['COLCON_PREFIX_PATH'], - 'ddsrouter_yaml_validator/share/ddsrouter_yaml_validator/' - 'ddsrouter_config_schema.json', - ), - help='JSON schema used to perform validation', - ) - return parser.parse_args() diff --git a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/validator.py b/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/validator.py deleted file mode 100644 index 201b702e1..000000000 --- a/tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/validator.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""DDS-Router YAML Validator class container.""" - -import json -import os - -import jsonschema - -import yaml - - -class YamlValidator: - """ - Used to validate DDS-Router YAML configuration files against a schema. - - It exposes a static method for this purpose. - DDS-Router configurations are YAML files, and the schema is in JSON format. - """ - - def validate(self, config_path, schema_path, recursive=True, logout=True): - """Validate configuration file or files under a directory.""" - if not self.__is_json(schema_path): - print( - 'The given schema {} is not a JSON file.'.format( - os.path.basename(schema_path) - ) - ) - return - - if os.path.isdir(config_path): - ret = True - visited_dirs = [] - for root, dirs, files in os.walk(config_path): - print(f'Scanning directory {root}') - if root not in visited_dirs: - visited_dirs.append(root) - for f in files: - if self.__is_yaml(f): - ret = ret and self.__validate_config_file( - os.path.join(root, f), schema_path, logout) - if not recursive: - break - return ret - else: - if self.__is_yaml(config_path): - return self.__validate_config_file( - config_path, schema_path, logout) - else: - print( - 'The given config file {} is not a YAML file.'.format( - os.path.basename(config_path))) - - def __validate_config_file(self, config_file_path, schema_path, - logout=True): - """Validate DDS-Router configuration file.""" - with open(schema_path) as json_file: - schema = json.load(json_file) - with open(config_file_path) as yaml_file: - config_yaml = yaml.safe_load(yaml_file) - config_json = json.loads(json.dumps(config_yaml)) - try: - jsonschema.validate(config_json, schema) - except jsonschema.exceptions.ValidationError as exception: - if logout: - print(exception) - return False - - if logout: - print(os.path.basename(config_file_path), - 'is a valid DDS-Router configuration file.') - return True - - def __is_json(self, file): - """ - Check if a file is a JSON file. - - :param file: The input file - :return: True if the file is an JSON file, False if not. - """ - return os.path.splitext(str(file))[-1] == '.json' - - def __is_yaml(self, file): - """ - Check if a file is a YAML file. - - :param file: The input file - :return: True if the file is an YAML file, False if not. - """ - ext = os.path.splitext(str(file))[-1] - return ext == '.yaml' or ext == '.yml' diff --git a/tools/ddsrouter_yaml_validator/package.xml b/tools/ddsrouter_yaml_validator/package.xml deleted file mode 100644 index 0b92759fe..000000000 --- a/tools/ddsrouter_yaml_validator/package.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - ddsrouter_yaml_validator - 3.5.1 - Tool used for validating DDS-Router configuration files - Raúl Sánchez-Mateos - Javier París - Juan López - Apache License, Version 2.0 - - python3-pytest - - - ament_python - - diff --git a/tools/ddsrouter_yaml_validator/resource/ddsrouter_yaml_validator b/tools/ddsrouter_yaml_validator/resource/ddsrouter_yaml_validator deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/ddsrouter_yaml_validator/setup.cfg b/tools/ddsrouter_yaml_validator/setup.cfg deleted file mode 100644 index 3c1f99b9e..000000000 --- a/tools/ddsrouter_yaml_validator/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script_dir=$base/bin -[install] -install_scripts=$base/bin diff --git a/tools/ddsrouter_yaml_validator/setup.py b/tools/ddsrouter_yaml_validator/setup.py deleted file mode 100644 index cde18500e..000000000 --- a/tools/ddsrouter_yaml_validator/setup.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Setup file to install ddsrouter_yaml_validator module.""" -from setuptools import setup - - -package_name = 'ddsrouter_yaml_validator' - -setup( - name=package_name, - version='3.5.1', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ('share/' + package_name, [package_name + '/ddsrouter_config_schema.json']), - ('share/' + package_name, [package_name + '/full_example.yaml']) - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='eprosima', - maintainer_email='juanlopez@eprosima.com', - description='Tool used for validating DDS-Router configuration files', - license='Apache License, Version 2.0', - tests_require=['pytest'], - test_suite='tests', - entry_points={ - 'console_scripts': [ - 'ddsrouter_yaml_validator = ddsrouter_yaml_validator.ddsrouter_yaml_validator:main', - ], - }, -) diff --git a/tools/ddsrouter_yaml_validator/tests/__init__.py b/tools/ddsrouter_yaml_validator/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/ddsrouter_yaml_validator/tests/ddsrouter_yaml_validator_test.py b/tools/ddsrouter_yaml_validator/tests/ddsrouter_yaml_validator_test.py deleted file mode 100644 index 9210ccac7..000000000 --- a/tools/ddsrouter_yaml_validator/tests/ddsrouter_yaml_validator_test.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""DDS-Router YAML Validator tests.""" - -import os - -from ddsrouter_yaml_validator.validator import YamlValidator - - -# Move to project root level -os.chdir(os.path.dirname(os.path.abspath(__file__)) + '/../../..') - -SCHEMA_PATH = 'tools/ddsrouter_yaml_validator/ddsrouter_yaml_validator/' \ - 'ddsrouter_config_schema.json' - -VALID_CONFIGURATION_FILES = [ - 'resources/configurations/examples', - 'docs/resources/getting_started'] - -INVALID_CONFIGURATION_FILES = [ - 'tools/ddsrouter_yaml_validator/tests/invalid_configuration_files'] - - -def test_valid_yamls(): - """Assert given configuration files are valid.""" - validator = YamlValidator() - for valid_files_dir in VALID_CONFIGURATION_FILES: - for root, dirs, files in os.walk(valid_files_dir): - for file in files: - file_path = os.path.join(root, file) - assert validator.validate(file_path, SCHEMA_PATH, logout=False), 'Test error: ' + file_path - - -def test_invalid_yamls(): - """Assert given configuration files are invalid.""" - validator = YamlValidator() - for invalid_files_dir in INVALID_CONFIGURATION_FILES: - assert not validator.validate( - invalid_files_dir, SCHEMA_PATH, logout=False), 'Negative test error: ' + invalid_files_dir diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_ip_nor_domain.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_ip_nor_domain.yaml deleted file mode 100644 index a00717b0d..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_ip_nor_domain.yaml +++ /dev/null @@ -1,35 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: discovery_participant - kind: discovery-server - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - listening-addresses: - - port: 11667 - transport: udp - ip-version: v4 - connection-addresses: - - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - addresses: - - ip: 127.0.0.1 - domain: localhost - port: 11667 - transport: udp - ip-version: v4 diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_port.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_port.yaml deleted file mode 100644 index 2bf6c27ab..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/address_no_port.yaml +++ /dev/null @@ -1,36 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: discovery_participant - kind: discovery-server - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - listening-addresses: - - ip: 127.0.0.1 - domain: localhost - transport: udp - ip-version: v4 - connection-addresses: - - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - addresses: - - ip: 127.0.0.1 - domain: localhost - port: 11667 - transport: udp - ip-version: v4 diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_name.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_name.yaml deleted file mode 100644 index 359c42c87..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_name.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: v5.0 - -builtin-topics: - - type: HelloWorld - - -participants: - - - name: SimpleParticipant - kind: local - domain: 0 - - - name: EchoParticipant - kind: echo diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_type.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_type.yaml deleted file mode 100644 index 443ba8b47..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/builtin_topic_no_type.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: v5.0 - -builtin-topics: - - name: HelloWorldTopic - - -participants: - - - name: SimpleParticipant - kind: local - domain: 0 - - - name: EchoParticipant - kind: echo diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_discovery_server_guid.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_discovery_server_guid.yaml deleted file mode 100644 index 576723c2c..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_discovery_server_guid.yaml +++ /dev/null @@ -1,33 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: discovery_participant - kind: discovery-server - listening-addresses: - - ip: 127.0.0.1 - domain: localhost - port: 11667 - transport: udp - ip-version: v4 - connection-addresses: - - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - addresses: - - ip: 127.0.0.1 - domain: localhost - port: 11667 - transport: udp - ip-version: v4 diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_listening_nor_connection_addresses.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_listening_nor_connection_addresses.yaml deleted file mode 100644 index 4c3452940..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/ds_participant_no_listening_nor_connection_addresses.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: discovery_participant - kind: discovery-server - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/filter_topic_no_name.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/filter_topic_no_name.yaml deleted file mode 100644 index 9dfbcae2d..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/filter_topic_no_name.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: v5.0 - -allowlist: - - type: HelloWorld - - -participants: - - - name: SimpleParticipant - kind: local - domain: 0 - - - name: EchoParticipant - kind: echo diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/initial_peers_no_addresses.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/initial_peers_no_addresses.yaml deleted file mode 100644 index ede89094a..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/initial_peers_no_addresses.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: ip_participant - kind: initial-peers diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_kind.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_kind.yaml deleted file mode 100644 index 9b4daad29..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_kind.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: SimpleParticipant - domain: 0 - - - name: EchoParticipant - kind: echo diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_name.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_name.yaml deleted file mode 100644 index e16f500a7..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_participant_name.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: SimpleParticipant - kind: local - domain: 0 - - - kind: echo diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_version.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_version.yaml deleted file mode 100644 index 722484f38..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/no_version.yaml +++ /dev/null @@ -1,15 +0,0 @@ -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: SimpleParticipant - kind: local - domain: 0 - - - name: EchoParticipant - kind: echo diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_ca_no_private_key_provided_cert.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_ca_no_private_key_provided_cert.yaml deleted file mode 100644 index 8080c1a63..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_ca_no_private_key_provided_cert.yaml +++ /dev/null @@ -1,40 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: wan_participant - kind: wan - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - listening-addresses: - - ip: ::1 - domain: localhost - port: 11667 - transport: tcp - ip-version: v6 - connection-addresses: - - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - addresses: - - ip: 127.0.0.1 - domain: localhost - port: 11667 - transport: tcp - ip-version: v4 - tls: - ca: ca.crt - cert: ddsrouter.crt diff --git a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_no_ca.yaml b/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_no_ca.yaml deleted file mode 100644 index 0129aca70..000000000 --- a/tools/ddsrouter_yaml_validator/tests/invalid_configuration_files/tls_no_ca.yaml +++ /dev/null @@ -1,42 +0,0 @@ -version: v5.0 - -allowlist: - - name: HelloWorldTopic - type: HelloWorld - - name: rt/chatter - type: std_msgs::msg::dds_::String_ - - -participants: - - - name: EchoParticipant - kind: echo - - - name: wan_participant - kind: wan - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - listening-addresses: - - ip: ::1 - domain: localhost - port: 11667 - transport: tcp - ip-version: v6 - connection-addresses: - - discovery-server-guid: - guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe - id: 0 - ros-discovery-server: true - addresses: - - ip: 127.0.0.1 - domain: localhost - port: 11667 - transport: tcp - ip-version: v4 - tls: - password: ddsrouterpass - private_key: ddsrouter.key - cert: ddsrouter.crt - dh_params: dh_params.pem From 7dc43579d2e547db558dae5d7c45b23022f8b290 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Tue, 23 Jun 2026 16:51:13 +0200 Subject: [PATCH 05/10] Add YAML validator to ddsrouter_yaml Signed-off-by: David Laseca Perez --- ddsrouter_yaml/CMakeLists.txt | 16 + .../DdsRouterConfigSchema.hpp.in | 17 + .../src/cpp/YamlReaderConfiguration.cpp | 11 + .../ddsrouter_config_schema.json | 1094 +++++++++++++++++ 4 files changed, 1138 insertions(+) create mode 100644 ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in create mode 100644 resources/configurations/ddsrouter_config_schema.json diff --git a/ddsrouter_yaml/CMakeLists.txt b/ddsrouter_yaml/CMakeLists.txt index e3e2414a1..5b9b27a26 100644 --- a/ddsrouter_yaml/CMakeLists.txt +++ b/ddsrouter_yaml/CMakeLists.txt @@ -74,6 +74,22 @@ compile_test_library( "${PROJECT_SOURCE_DIR}/test" # Test directory ) +############################################################################### +# Resources +############################################################################### +file(READ "${PROJECT_SOURCE_DIR}/../resources/configurations/ddsrouter_config_schema.json" + DDSROUTER_CONFIG_SCHEMA_CONTENT) + +configure_file( + "${PROJECT_SOURCE_DIR}/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in" + "${CMAKE_CURRENT_BINARY_DIR}/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp" + @ONLY +) + +target_include_directories(${MODULE_NAME} PUBLIC + $ +) + ############################################################################### # Packaging ############################################################################### diff --git a/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in b/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in new file mode 100644 index 000000000..87e41126a --- /dev/null +++ b/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in @@ -0,0 +1,17 @@ +// Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +static const char* DDSROUTER_CONFIG_SCHEMA = R"json(@DDSROUTER_CONFIG_SCHEMA_CONTENT@)json"; diff --git a/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp b/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp index acfba8669..172aa8995 100644 --- a/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp +++ b/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp @@ -16,10 +16,12 @@ #include #include #include +#include #include #include +#include namespace eprosima { namespace ddsrouter { @@ -30,6 +32,15 @@ YamlReaderConfiguration::load_ddsrouter_configuration( const Yaml& yml, const CommandlineArgsRouter* args /*= nullptr*/) { + // Ensure the Yaml is valid + ddspipe::yaml::YamlValidator validator = ddspipe::yaml::YamlValidator( + ddspipe::yaml::YamlValidator::from_string(DDSROUTER_CONFIG_SCHEMA)); + if (!validator.validate_YAML(yml)) + { + throw eprosima::utils::ConfigurationException( + utils::Formatter() << "Error, the provided yaml file is not a valid ddsrouter configuration.\n"); + } + try { ddspipe::yaml::YamlReaderVersion version; diff --git a/resources/configurations/ddsrouter_config_schema.json b/resources/configurations/ddsrouter_config_schema.json new file mode 100644 index 000000000..dcef3d5b9 --- /dev/null +++ b/resources/configurations/ddsrouter_config_schema.json @@ -0,0 +1,1094 @@ +{ + "$schema":"http://json-schema.org/draft-07/schema#", + "$ref":"#/definitions/BaseObject", + "definitions":{ + "BaseObject":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "version":{ + "type":"string", + "enum":[ + "v4.0", + "v5.0" + ] + }, + "specs":{ + "$ref":"#/definitions/SpecsConfig" + }, + "allowlist":{ + "type":"array", + "items":{ + "$ref":"#/definitions/TopicFilter" + } + }, + "blocklist":{ + "type":"array", + "items":{ + "$ref":"#/definitions/TopicFilter" + } + }, + "builtin-topics":{ + "type":"array", + "items":{ + "$ref":"#/definitions/TopicBuiltins" + } + }, + "routes":{ + "type":"array", + "items":{ + "$ref":"#/definitions/RouteConfig" + } + }, + "topic-routes":{ + "type":"array", + "items":{ + "$ref":"#/definitions/TopicRouteConfig" + } + }, + "topics":{ + "type":"array", + "items":{ + "$ref":"#/definitions/ManualTopic" + } + }, + "participants":{ + "type":"array", + "minItems":1, + "items":{ + "$ref":"#/definitions/Participant" + }, + "uniqueKeys":[ + "/name" + ] + }, + "xml":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "raw":{ + "type":"string" + }, + "files":{ + "type":"array", + "minItems":1, + "items":{ + "type":"string" + } + } + }, + "anyOf":[ + { + "required":[ + "raw" + ] + }, + { + "required":[ + "files" + ] + } + ] + } + }, + "required":[ + "participants" + ], + "title":"BaseObject" + }, + "SpecsConfig":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "threads":{ + "type":"integer", + "minimum": 0 + }, + "remove-unused-entities":{ + "type":"boolean" + }, + "qos":{ + "$ref":"#/definitions/QOS" + }, + "discovery-trigger":{ + "type":"string", + "pattern":"^([Rr][Ee][Aa][Dd][Ee][Rr]|[Ww][Rr][Ii][Tt][Ee][Rr]|[Aa][Nn][Yy]|[Nn][Oo][Nn][Ee])$" + }, + "logging":{ + "$ref":"#/definitions/LogConfig" + }, + "monitor":{ + "$ref":"#/definitions/MonitorConfig" + } + } + }, + "QOS":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "durability":{ + "type":"boolean" + }, + "reliability":{ + "type":"boolean" + }, + "ownership":{ + "type":"boolean" + }, + "partitions":{ + "type":"boolean" + }, + "history-depth":{ + "type":"integer", + "minimum":0 + }, + "keyed":{ + "type":"boolean" + }, + "max-tx-rate":{ + "type":"number", + "minimum": 0 + }, + "max-rx-rate":{ + "type":"number", + "minimum": 0 + }, + "downsampling":{ + "type":"integer", + "minimum": 1 + } + }, + "title": "QOS" + }, + "LogConfig":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "publish":{ + "type":"object", + "additionalProperties": false, + "properties": { + "enable":{ + "type":"boolean" + }, + "domain":{ + "$ref":"#/definitions/DdsDomain" + }, + "topic-name":{ + "type":"string" + } + }, + "required": [ + "enable" + ] + }, + "stdout":{ + "type":"boolean" + }, + "verbosity":{ + "type":"string", + "enum":[ + "info", + "warning", + "error" + ] + }, + "filter":{ + "type":"object", + "additionalProperties": false, + "properties": { + "info":{ + "type":"string" + }, + "warning":{ + "type":"string" + }, + "error":{ + "type":"string" + } + } + } + } + }, + "MonitorConfig":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "domain":{ + "$ref":"#/definitions/DdsDomain" + }, + "status":{ + "$ref":"#/definitions/MonitorProducerConfig" + }, + "topics":{ + "$ref":"#/definitions/MonitorProducerConfig" + } + }, + "title": "MonitorConfig" + }, + "MonitorProducerConfig":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "enable":{ + "type":"boolean" + }, + "domain":{ + "$ref":"#/definitions/DdsDomain" + }, + "period":{ + "type":"number", + "exclusiveMinimum": 0 + }, + "topic-name":{ + "type":"string" + } + }, + "required":[ + "enable" + ], + "title": "MonitorProducerConfig" + }, + "TopicFilter":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "name":{ + "type":"string" + }, + "type":{ + "type":"string" + }, + "qos":{ + "$ref":"#/definitions/QOS" + }, + "filter":{ + "type":"string" + } + }, + "required":[ + "name" + ], + "title":"TopicFilter" + }, + "TopicBuiltins":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "name":{ + "type":"string" + }, + "type":{ + "type":"string" + } + }, + "required":[ + "name", + "type" + ], + "title":"TopicBuiltins" + }, + "RouteConfig":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "src":{ + "type":"string" + }, + "dst":{ + "type":"array", + "items":{ + "type":"string" + } + } + }, + "required":[ + "src" + ], + "title":"RouteConfig" + }, + "TopicRouteConfig":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "name":{ + "type":"string" + }, + "type":{ + "type":"string" + }, + "routes":{ + "type":"array", + "items":{ + "$ref":"#/definitions/RouteConfig" + } + } + }, + "required":[ + "name", + "type" + ], + "title":"TopicRouteConfig" + }, + "ManualTopic":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "name":{ + "type":"string" + }, + "type":{ + "type":"string" + }, + "qos":{ + "$ref":"#/definitions/QOS" + }, + "filter":{ + "type":"string" + }, + "participants":{ + "type":"array", + "items":{ + "type":"string" + } + } + }, + "required":[ + "name" + ], + "title":"ManualTopic" + }, + "Participant":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "name":{ + "type":"string" + }, + "kind":{ + "type":"string", + "enum":[ + "echo", + "local", + "simple", + "wan", + "router", + "initial-peers", + "discovery-server", + "ds", + "local-ds", + "local-discovery-server", + "wan-ds", + "wan-discovery-server", + "xml", + "XML" + ] + }, + "domain":{ + "$ref":"#/definitions/DdsDomain" + }, + "repeater":{ + "type":"boolean" + }, + "discovery-server-guid":{ + "$ref":"#/definitions/DiscoveryServerGUID" + }, + "listening-addresses":{ + "type":"array", + "minItems":1, + "items":{ + "$ref":"#/definitions/Address" + } + }, + "connection-addresses":{ + "type":"array", + "minItems":1, + "items":{ + "$ref":"#/definitions/Address" + } + }, + "tls":{ + "$ref":"#/definitions/TLS" + }, + "discovery":{ + "type":"boolean" + }, + "data":{ + "type":"boolean" + }, + "verbose":{ + "type":"boolean" + }, + "whitelist-interfaces":{ + "type":"array", + "items":{ + "type":"string" + } + }, + "ros2-easy-mode":{ + "$ref":"#/definitions/IPv4" + }, + "transport":{ + "type":"string", + "enum":[ + "builtin", + "udp", + "shm" + ] + }, + "ignore-participant-flags":{ + "type":"string", + "enum":[ + "no_filter", + "filter_different_host", + "filter_different_process", + "filter_same_process", + "filter_different_and_same_process" + ] + }, + "qos":{ + "$ref":"#/definitions/QOS" + }, + "profile":{ + "type":"string" + } + }, + "required":[ + "kind", + "name" + ], + "allOf":[ + { + "if":{ + "properties":{ + "kind":{ + "type":"string", + "enum":[ + "echo" + ] + } + } + }, + "then":{ + "properties":{ + "domain":{ + "not":{ + + } + }, + "discovery-server-guid":{ + "not":{ + + } + }, + "listening-addresses":{ + "not":{ + + } + }, + "connection-addresses":{ + "not":{ + + } + }, + "tls":{ + "not":{ + + } + }, + "repeater":{ + "not":{ + + } + }, + "whitelist-interfaces":{ + "not":{ + + } + }, + "ros2-easy-mode":{ + "not":{ + + } + }, + "transport":{ + "not":{ + + } + }, + "ignore-participant-flags":{ + "not":{ + + } + }, + "qos":{ + "not":{ + + } + }, + "profile":{ + "not":{ + + } + } + } + } + }, + { + "if":{ + "properties":{ + "kind":{ + "type":"string", + "enum":[ + "local", + "simple" + ] + } + } + }, + "then":{ + "allOf":[ + { + "properties":{ + "discovery-server-guid":{ + "not":{ + + } + }, + "listening-addresses":{ + "not":{ + + } + }, + "connection-addresses":{ + "not":{ + + } + }, + "tls":{ + "not":{ + + } + }, + "repeater":{ + "not":{ + + } + }, + "discovery":{ + "not":{ + + } + }, + "data":{ + "not":{ + + } + }, + "verbose":{ + "not":{ + + } + }, + "profile":{ + "not":{ + + } + } + } + } + ] + } + }, + { + "if":{ + "properties":{ + "kind":{ + "type":"string", + "enum":[ + "discovery-server", + "ds", + "local-ds", + "local-discovery-server", + "wan-ds", + "wan-discovery-server" + ] + } + } + }, + "then":{ + "allOf":[ + { + "properties":{ + "domain":{ + "not":{ + + } + }, + "repeater":{ + "not":{ + + } + }, + "discovery":{ + "not":{ + + } + }, + "data":{ + "not":{ + + } + }, + "verbose":{ + "not":{ + + } + }, + "profile":{ + "not":{ + + } + } + } + }, + { + "anyOf":[ + { + "required":[ + "listening-addresses" + ] + }, + { + "required":[ + "connection-addresses" + ] + } + ] + } + ] + } + }, + { + "if":{ + "properties":{ + "kind":{ + "type":"string", + "enum":[ + "wan", + "router", + "initial-peers" + ] + } + } + }, + "then":{ + "allOf":[ + { + "properties":{ + "discovery-server-guid":{ + "not":{ + + } + }, + "discovery":{ + "not":{ + + } + }, + "data":{ + "not":{ + + } + }, + "verbose":{ + "not":{ + + } + }, + "profile":{ + "not":{ + + } + } + } + }, + { + "anyOf":[ + { + "required":[ + "listening-addresses" + ] + }, + { + "required":[ + "connection-addresses" + ] + } + ] + } + ] + } + }, + { + "if":{ + "properties":{ + "kind":{ + "type":"string", + "enum":[ + "xml", + "XML" + ] + } + } + }, + "then":{ + "allOf":[ + { + "properties":{ + "domain":{ + "not":{ + + } + }, + "discovery-server-guid":{ + "not":{ + + } + }, + "listening-addresses":{ + "not":{ + + } + }, + "connection-addresses":{ + "not":{ + + } + }, + "tls":{ + "not":{ + + } + }, + "discovery":{ + "not":{ + + } + }, + "data":{ + "not":{ + + } + }, + "verbose":{ + "not":{ + + } + }, + "whitelist-interfaces":{ + "not":{ + + } + }, + "ros2-easy-mode":{ + "not":{ + + } + }, + "transport":{ + "not":{ + + } + }, + "ignore-participant-flags":{ + "not":{ + + } + }, + "qos":{ + "not":{ + + } + } + } + }, + { + "required":[ + "profile" + ] + } + ] + } + } + ], + "title":"Participant" + }, + "DiscoveryServerGUID":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "guid":{ + "type":"string" + }, + "id":{ + "type":"integer", + "minimum": 0 + }, + "ros-discovery-server":{ + "type":"boolean" + } + }, + "anyOf":[ + { + "required":[ + "guid" + ] + }, + { + "required":[ + "id" + ] + } + ], + "title":"DiscoveryServerGUID" + }, + "TLS":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "ca":{ + "type":"string" + }, + "password":{ + "type":"string" + }, + "private_key":{ + "type":"string" + }, + "cert":{ + "type":"string" + }, + "dh_params":{ + "type":"string" + }, + "peer_verification":{ + "type":"boolean" + }, + "sni_host":{ + "type":"string" + } + }, + "required":[ + "ca" + ], + "allOf":[ + { + "if":{ + "properties":{ + "password":{ + "type":"string" + } + }, + "required":[ + "password" + ] + }, + "then":{ + "required":[ + "private_key", + "cert" + ] + } + }, + { + "if":{ + "properties":{ + "private_key":{ + "not":{ + "pattern":"^$" + } + } + }, + "required":[ + "private_key" + ] + }, + "then":{ + "properties":{ + "private_key":{ + "not":{ + "pattern":"^\\s*$" + } + } + }, + "required":[ + "password", + "cert" + ] + } + }, + { + "if":{ + "properties":{ + "cert":{ + "type":"string" + } + }, + "required":[ + "cert" + ] + }, + "then":{ + "properties":{ + "cert":{ + "not":{ + "pattern":"^\\s*$" + } + } + }, + "required":[ + "password", + "private_key" + ] + } + } + ], + "title":"TLS" + }, + "Address":{ + "type":"object", + "additionalProperties":false, + "properties":{ + "ip":{ + "type":"string" + }, + "domain":{ + "type":"string" + }, + "port":{ + "type":"integer", + "minimum":0, + "maximum":65535 + }, + "external-port":{ + "type":"integer", + "minimum":0, + "maximum":65535 + }, + "transport":{ + "type":"string", + "enum":[ + "tcp", + "udp" + ] + }, + "ip-version":{ + "type":"string", + "enum":[ + "v4", + "v6" + ] + } + }, + "allOf":[ + { + "anyOf":[ + { + "required":[ + "domain" + ] + }, + { + "required":[ + "ip" + ] + } + ] + }, + { + "if": { + "not": { + "required": ["ip-version"] + } + }, + "then": { + "properties": { + "ip": { + "anyOf":[ + { + "format":"v4" + }, + { + "format":"v6" + } + ] + } + } + } + }, + { + "if":{ + "properties":{ + "ip-version":{ + "type":"string", + "enum":[ + "v4" + ] + } + }, + "required":[ + "ip-version" + ] + }, + "then":{ + "properties":{ + "ip":{ + "format": "v4" + } + } + } + }, + { + "if":{ + "properties":{ + "ip-version":{ + "type":"string", + "enum":[ + "v6" + ] + } + }, + "required":[ + "ip-version" + ] + }, + "then":{ + "properties":{ + "ip":{ + "format": "v6" + } + } + } + }, + { + "required":[ + "port" + ] + } + ], + "title":"Address" + }, + "IPv4":{ + "type":"string", + "format":"v4", + "title":"IPv4" + }, + "DdsDomain":{ + "type":"integer", + "minimum": 0, + "maximum": 232, + "title":"DdsDomain" + } + } +} From 3c16100d0cc5c7524ad72359412997fb31c5d5db Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Tue, 23 Jun 2026 16:53:18 +0200 Subject: [PATCH 06/10] Add tests for the router YAML validator and JSON schema Signed-off-by: David Laseca Perez --- ddsrouter_yaml/test/unittest/CMakeLists.txt | 1 + .../ddsrouter_yaml_validator/CMakeLists.txt | 77 +++++++ .../YamlValidatorDdsRouterTest.cpp | 102 +++++++++ .../address_no_ip_nor_domain.yaml | 35 ++++ .../address_no_port.yaml | 36 ++++ .../builtin_topic_no_name.yaml | 14 ++ .../builtin_topic_no_type.yaml | 14 ++ ..._participant_no_discovery_server_guid.yaml | 33 +++ ...no_listening_nor_connection_addresses.yaml | 20 ++ .../filter_topic_no_name.yaml | 14 ++ .../initial_peers_no_addresses.yaml | 16 ++ .../invalid_version.yaml | 17 ++ .../no_participant_kind.yaml | 16 ++ .../no_participant_name.yaml | 16 ++ .../tls_ca_no_private_key_provided_cert.yaml | 40 ++++ .../tls_no_ca.yaml | 42 ++++ .../docu_example.yaml | 194 ++++++++++++++++++ 17 files changed, 687 insertions(+) create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/CMakeLists.txt create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_ip_nor_domain.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_port.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_name.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_type.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_discovery_server_guid.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_listening_nor_connection_addresses.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/filter_topic_no_name.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/initial_peers_no_addresses.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/invalid_version.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_kind.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_name.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_ca_no_private_key_provided_cert.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_no_ca.yaml create mode 100644 ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/valid_config_files_router/docu_example.yaml diff --git a/ddsrouter_yaml/test/unittest/CMakeLists.txt b/ddsrouter_yaml/test/unittest/CMakeLists.txt index 38cbace2d..acbc6281d 100644 --- a/ddsrouter_yaml/test/unittest/CMakeLists.txt +++ b/ddsrouter_yaml/test/unittest/CMakeLists.txt @@ -19,3 +19,4 @@ # TODO uncomment when new API applied add_subdirectory(configuration) add_subdirectory(participants) +add_subdirectory(ddsrouter_yaml_validator) diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/CMakeLists.txt b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/CMakeLists.txt new file mode 100644 index 000000000..cde06694a --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/CMakeLists.txt @@ -0,0 +1,77 @@ +# Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +################################# +# DdsRouter Yaml Validator Test # +################################# + +set(TEST_NAME YamlValidatorDdsRouterTest) + + +set(TEST_SOURCES + YamlValidatorDdsRouterTest.cpp + ) + +set(TEST_LIST + validation_passed + validation_failed + ) + +set(TEST_EXTRA_LIBRARIES + yaml-cpp + fastcdr + fastdds + cpp_utils + ddspipe_core + ddspipe_participants + ddspipe_yaml + ) + +configure_file( + "${PROJECT_SOURCE_DIR}/../resources/configurations/ddsrouter_config_schema.json" + "${CMAKE_CURRENT_BINARY_DIR}/ddsrouter_config_schema.json" + COPYONLY +) + +file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/valid_config_files_router/") +file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/invalid_config_files_router/") + +file(GLOB_RECURSE TEST_NEEDED_SOURCES + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + "invalid_config_files_router/*.yaml" + "valid_config_files_router/*.yaml" +) + +file(GLOB GETTING_STARTED_YAMLS + "${PROJECT_SOURCE_DIR}/../docs/resources/getting_started/*.yaml" +) +file(COPY ${GETTING_STARTED_YAMLS} + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/valid_config_files_router/" +) + +file(GLOB EXAMPLES_YAMLS + "${PROJECT_SOURCE_DIR}/../resources/configurations/examples/*.yaml" +) +file(COPY ${EXAMPLES_YAMLS} + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/valid_config_files_router/" +) + +add_unittest_executable( + "${TEST_NAME}" + "${TEST_SOURCES}" + "${TEST_LIST}" + "${TEST_EXTRA_LIBRARIES}" + "${TEST_NEEDED_SOURCES}" +) + diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp new file mode 100644 index 000000000..e0cd89ae7 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp @@ -0,0 +1,102 @@ +// Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include +#include + +#include +#include + +using namespace eprosima; +using namespace eprosima::ddspipe::yaml; + +namespace test { +// Paths and files for the tests +std::string schema_path = "./ddsrouter_config_schema.json"; + +// Vectors with the valid and invalid YAML files +std::vector valid_files = []() +{ + std::vector files; + for (const auto& entry : std::filesystem::directory_iterator("./valid_config_files_router/")) + { + if (entry.path().extension() == ".yaml") + { + files.push_back(entry.path().generic_string()); + } + } + return files; +}(); + +std::vector invalid_files = []() +{ + std::vector files; + for (const auto& entry : std::filesystem::directory_iterator("./invalid_config_files_router/")) + { + if (entry.path().extension() == ".yaml") + { + files.push_back(entry.path().generic_string()); + } + } + return files; +}(); +} // namespace test + +/** + * Test that a set of valid YAML configurations pass the validation + */ +TEST(YamlValidatorDdsRouterTest, validation_passed) +{ + YamlValidator validator = YamlValidator(YamlValidator::from_file(test::schema_path)); + + // valid files + { + for (std::string st : test::valid_files) + { + Yaml yml = YamlManager::load_file(st); + ASSERT_TRUE(validator.validate_YAML(yml)) << "Failed for file: " << st; + } + } + +} + +/** + * Test that a set of invalid YAML configurations don't pass the validation + */ +TEST(YamlValidatorDdsRouterTest, validation_failed) +{ + YamlValidator validator = YamlValidator(YamlValidator::from_file(test::schema_path)); + + // invalid files + { + for (std::string st : test::invalid_files) + { + Yaml yml = YamlManager::load_file(st); + // Validate is called with false to prevent filling the output with the specific errors + ASSERT_FALSE(validator.validate_YAML(yml, false)) << "Failed for file: " << st; + } + } +} + +int main( + int argc, + char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_ip_nor_domain.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_ip_nor_domain.yaml new file mode 100644 index 000000000..a00717b0d --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_ip_nor_domain.yaml @@ -0,0 +1,35 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: discovery_participant + kind: discovery-server + discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + listening-addresses: + - port: 11667 + transport: udp + ip-version: v4 + connection-addresses: + - discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + addresses: + - ip: 127.0.0.1 + domain: localhost + port: 11667 + transport: udp + ip-version: v4 diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_port.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_port.yaml new file mode 100644 index 000000000..2bf6c27ab --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/address_no_port.yaml @@ -0,0 +1,36 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: discovery_participant + kind: discovery-server + discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + listening-addresses: + - ip: 127.0.0.1 + domain: localhost + transport: udp + ip-version: v4 + connection-addresses: + - discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + addresses: + - ip: 127.0.0.1 + domain: localhost + port: 11667 + transport: udp + ip-version: v4 diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_name.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_name.yaml new file mode 100644 index 000000000..359c42c87 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_name.yaml @@ -0,0 +1,14 @@ +version: v5.0 + +builtin-topics: + - type: HelloWorld + + +participants: + + - name: SimpleParticipant + kind: local + domain: 0 + + - name: EchoParticipant + kind: echo diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_type.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_type.yaml new file mode 100644 index 000000000..443ba8b47 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/builtin_topic_no_type.yaml @@ -0,0 +1,14 @@ +version: v5.0 + +builtin-topics: + - name: HelloWorldTopic + + +participants: + + - name: SimpleParticipant + kind: local + domain: 0 + + - name: EchoParticipant + kind: echo diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_discovery_server_guid.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_discovery_server_guid.yaml new file mode 100644 index 000000000..576723c2c --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_discovery_server_guid.yaml @@ -0,0 +1,33 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: discovery_participant + kind: discovery-server + listening-addresses: + - ip: 127.0.0.1 + domain: localhost + port: 11667 + transport: udp + ip-version: v4 + connection-addresses: + - discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + addresses: + - ip: 127.0.0.1 + domain: localhost + port: 11667 + transport: udp + ip-version: v4 diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_listening_nor_connection_addresses.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_listening_nor_connection_addresses.yaml new file mode 100644 index 000000000..4c3452940 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/ds_participant_no_listening_nor_connection_addresses.yaml @@ -0,0 +1,20 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: discovery_participant + kind: discovery-server + discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/filter_topic_no_name.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/filter_topic_no_name.yaml new file mode 100644 index 000000000..9dfbcae2d --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/filter_topic_no_name.yaml @@ -0,0 +1,14 @@ +version: v5.0 + +allowlist: + - type: HelloWorld + + +participants: + + - name: SimpleParticipant + kind: local + domain: 0 + + - name: EchoParticipant + kind: echo diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/initial_peers_no_addresses.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/initial_peers_no_addresses.yaml new file mode 100644 index 000000000..ede89094a --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/initial_peers_no_addresses.yaml @@ -0,0 +1,16 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: ip_participant + kind: initial-peers diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/invalid_version.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/invalid_version.yaml new file mode 100644 index 000000000..dbfba1bea --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/invalid_version.yaml @@ -0,0 +1,17 @@ +version: v4.1 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: SimpleParticipant + kind: local + domain: 0 + + - name: EchoParticipant + kind: echo diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_kind.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_kind.yaml new file mode 100644 index 000000000..9b4daad29 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_kind.yaml @@ -0,0 +1,16 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: SimpleParticipant + domain: 0 + + - name: EchoParticipant + kind: echo diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_name.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_name.yaml new file mode 100644 index 000000000..e16f500a7 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/no_participant_name.yaml @@ -0,0 +1,16 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: SimpleParticipant + kind: local + domain: 0 + + - kind: echo diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_ca_no_private_key_provided_cert.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_ca_no_private_key_provided_cert.yaml new file mode 100644 index 000000000..8080c1a63 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_ca_no_private_key_provided_cert.yaml @@ -0,0 +1,40 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: wan_participant + kind: wan + discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + listening-addresses: + - ip: ::1 + domain: localhost + port: 11667 + transport: tcp + ip-version: v6 + connection-addresses: + - discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + addresses: + - ip: 127.0.0.1 + domain: localhost + port: 11667 + transport: tcp + ip-version: v4 + tls: + ca: ca.crt + cert: ddsrouter.crt diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_no_ca.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_no_ca.yaml new file mode 100644 index 000000000..0129aca70 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/invalid_config_files_router/tls_no_ca.yaml @@ -0,0 +1,42 @@ +version: v5.0 + +allowlist: + - name: HelloWorldTopic + type: HelloWorld + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + +participants: + + - name: EchoParticipant + kind: echo + + - name: wan_participant + kind: wan + discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + listening-addresses: + - ip: ::1 + domain: localhost + port: 11667 + transport: tcp + ip-version: v6 + connection-addresses: + - discovery-server-guid: + guid: 01.0f.00.00.00.00.00.00.00.00.ca.fe + id: 0 + ros-discovery-server: true + addresses: + - ip: 127.0.0.1 + domain: localhost + port: 11667 + transport: tcp + ip-version: v4 + tls: + password: ddsrouterpass + private_key: ddsrouter.key + cert: ddsrouter.crt + dh_params: dh_params.pem diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/valid_config_files_router/docu_example.yaml b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/valid_config_files_router/docu_example.yaml new file mode 100644 index 000000000..2b45c8d04 --- /dev/null +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/valid_config_files_router/docu_example.yaml @@ -0,0 +1,194 @@ +# Specifications +specs: + threads: 10 + remove-unused-entities: false + discovery-trigger: reader + + qos: + history-depth: 1000 + max-tx-rate: 0 + max-rx-rate: 20 + downsampling: 3 + + logging: + verbosity: info + filter: + error: "DDSPIPE|DDSROUTER" + warning: "DDSPIPE|DDSROUTER" + info: "DDSROUTER" + publish: + enable: true + domain: 84 + topic-name: "DdsRouterLogs" + stdout: true + + monitor: + topics: + enable: true + period: 1000 + domain: 10 + topic-name: "DdsRouterTopicStatistics" + +# XML configurations to load +xml: + + # Load this file as Fast DDS XML configuration + files: + - "./xml_configuration.xml" + + # Load text as Fast DDS XML configuration + raw: | + + + + 1 + + + + +# Relay topic rt/chatter and type std_msgs::msg::dds_::String_ +# Relay topic HelloWorldTopic and type HelloWorld + +builtin-topics: + + - name: rt/chatter + type: std_msgs::msg::dds_::String_ + + - name: HelloWorldTopic + type: HelloWorld + +# Manually configure Topic QoS for a set of participants on a topic + +topics: + + - name: "temperature/*" + type: "temperature/types/*" + qos: + max-tx-rate: 15 + downsampling: 2 + participants: + - Participant0 + - Participant1 + +# Do not allow ROS2 services + +blocklist: + - name: "rr/*" + - name: "rq/*" + + +participants: + +#################### + +# Simple DDS Participant in domain 3 + + - name: Participant0 # Participant Name = Participant0 + + kind: local # Participant Kind = local (= simple) + + domain: 3 # DomainId = 3 + + qos: + + max-rx-rate: 0 # Max Reception Rate = 0 (unlimited) + + downsampling: 1 # Downsampling = 1 + +#################### + +# Simple DDS Participant in domain 7 + + - name: Participant1 # Participant Name = Participant1 + + kind: local # Participant Kind = local (= simple) + + domain: 7 # DomainId = 7 + + qos: + + max-rx-rate: 15 # Max Reception Rate = 15 + +#################### + +# Simple DDS Participant configured with ROS 2 Easy Mode + + - name: Participant1 # Participant Name = Participant1 + + kind: simple # Participant Kind = local (= simple) + + domain: 7 # DomainId = 7 + + ros2-easy-mode: "2.2.2.2" # Remote discovery server address + +#################### + +# Discovery Server DDS Participant with ROS GuidPrefix so a local ROS 2 Client could connect to it +# This Discovery Server will listen in ports 11600 and 11601 in localhost + + - name: ServerROS2 # Participant Name = ServerROS2 + + kind: local-discovery-server # Participant Kind = local-discovery-server + + discovery-server-guid: + id: 1 + ros-discovery-server: true # ROS Discovery Server id => GuidPrefix = 44.53.01.5f.45.50.52.4f.53.49.4d.41 + + listening-addresses: # Local Discovery Server Listening Addresses + - ip: 127.0.0.1 # IP = localhost ; Transport = UDP (by default) + port: 11600 # Port = 11600 + - ip: 127.0.0.1 # IP = localhost + port: 11601 # Port = 11601 + external-port: 11602 # External Port = 11602 + transport: tcp # Transport = TCP + + connection-addresses: + - domain: "localhost" + port: 22000 + +#################### + +# Participant that will communicate with a DDS Router in a different LAN. +# This Participant will work as the remote DDS Router Client, so it sets the connection address of the remote one. + + - name: Wan # Participant Name = Wan + + kind: wan-ds # Participant Kind = Discovery Server WAN + + discovery-server-guid: + id: 2 # Internal WAN Discovery Server id => GuidPrefix = 01.0f.02.00.00.00.00.00.00.00.ca.fe + + connection-addresses: # WAN Discovery Server Connection Addresses + - ip: 8.8.8.8 # IP = 8.8.8.8 + port: 11666 # Port = 11666 + transport: udp # Transport = UDP + + +#################### + +# Participant that will use a user set configuration via QoS Profile. + + - name: xml_participant # Participant Name = xml_participant + + kind: xml + + profile: custom_participant_configuration # Configure participant with this profile + +# Custom generic forwarding route. + +routes: + + - src: Participant0 + dst: + - Participant1 + +# Custom topic forwarding route. + +topic-routes: + + - name: HelloWorld + type: HelloWorld + routes: + - src: Participant1 + dst: + - Participant0 \ No newline at end of file From 7e240f6ff4ff5950046033ea957a1d91965cd6ba Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Tue, 23 Jun 2026 16:54:10 +0200 Subject: [PATCH 07/10] Fix issue in ddsrouter_tool CI Signed-off-by: David Laseca Perez --- .../test/application/configurations/complex_configuration.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/ddsrouter_tool/test/application/configurations/complex_configuration.yaml b/tools/ddsrouter_tool/test/application/configurations/complex_configuration.yaml index 36a12d75d..c42e26ab8 100644 --- a/tools/ddsrouter_tool/test/application/configurations/complex_configuration.yaml +++ b/tools/ddsrouter_tool/test/application/configurations/complex_configuration.yaml @@ -75,9 +75,10 @@ participants: port: 11668 transport: tcp - ip: "0.0.0.0" + port: 11669 listening-addresses: - ip: "127.0.0.1" - port: 11669 + port: 11670 - name: XML-DDS kind: xml From 6f635cef32bcf40118b4f34ed4d48a47ea6b7749 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Tue, 23 Jun 2026 17:18:13 +0200 Subject: [PATCH 08/10] Fix uncrustify Signed-off-by: David Laseca Perez --- .../src/cpp/YamlReaderConfiguration.cpp | 27 +++++++------ .../YamlValidatorDdsRouterTest.cpp | 40 +++++++++---------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp b/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp index 172aa8995..0743fc8e1 100644 --- a/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp +++ b/ddsrouter_yaml/src/cpp/YamlReaderConfiguration.cpp @@ -63,15 +63,16 @@ YamlReaderConfiguration::load_ddsrouter_configuration( default: throw eprosima::utils::ConfigurationException( - utils::Formatter() << - "The yaml configuration version " << version << - " is no longer supported. Please update to v5.0."); + utils::Formatter() + << "The yaml configuration version " << version + << " is no longer supported. Please update to v5.0."); break; case ddspipe::yaml::YamlReaderVersion::V_4_0: EPROSIMA_LOG_WARNING(DDSROUTER_YAML, - "The yaml configuration version " << version << - " is deprecated and will be removed in a future release. Please update to v5.0."); + "The yaml configuration version " + << version + << " is deprecated and will be removed in a future release. Please update to v5.0."); break; } } @@ -80,9 +81,11 @@ YamlReaderConfiguration::load_ddsrouter_configuration( // Get default version version = default_yaml_version(); EPROSIMA_LOG_WARNING(DDSROUTER_YAML, - "No version of yaml configuration given. Using version " << version << " by default. " << - "Add " << ddspipe::yaml::VERSION_TAG << " tag to your configuration in order to not break compatibility " << - "in future releases."); + "No version of yaml configuration given. Using version " + << version << " by default. " + << "Add " << ddspipe::yaml::VERSION_TAG + << " tag to your configuration in order to not break compatibility " + << "in future releases."); } EPROSIMA_LOG_INFO(DDSROUTER_YAML, "Loading DDSRouter configuration with version: " << version << "."); @@ -122,15 +125,15 @@ YamlReaderConfiguration::load_ddsrouter_configuration_from_file( catch (const std::exception& e) { throw eprosima::utils::ConfigurationException( - utils::Formatter() << "Error loading DDSRouter configuration from file: <" << file_path << - "> :\n " << e.what()); + utils::Formatter() << "Error loading DDSRouter configuration from file: <" << file_path + << "> :\n " << e.what()); } if (yml.IsNull()) { throw eprosima::utils::ConfigurationException( - utils::Formatter() << "Error loading DDSRouter configuration from file: <" << file_path << - "> :\n " << "yaml node is null."); + utils::Formatter() << "Error loading DDSRouter configuration from file: <" << file_path + << "> :\n " << "yaml node is null."); } return YamlReaderConfiguration::load_ddsrouter_configuration(yml, args); diff --git a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp index e0cd89ae7..ba97866ac 100644 --- a/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp +++ b/ddsrouter_yaml/test/unittest/ddsrouter_yaml_validator/YamlValidatorDdsRouterTest.cpp @@ -31,30 +31,30 @@ std::string schema_path = "./ddsrouter_config_schema.json"; // Vectors with the valid and invalid YAML files std::vector valid_files = []() -{ - std::vector files; - for (const auto& entry : std::filesystem::directory_iterator("./valid_config_files_router/")) - { - if (entry.path().extension() == ".yaml") { - files.push_back(entry.path().generic_string()); - } - } - return files; -}(); + std::vector files; + for (const auto& entry : std::filesystem::directory_iterator("./valid_config_files_router/")) + { + if (entry.path().extension() == ".yaml") + { + files.push_back(entry.path().generic_string()); + } + } + return files; + }(); std::vector invalid_files = []() -{ - std::vector files; - for (const auto& entry : std::filesystem::directory_iterator("./invalid_config_files_router/")) - { - if (entry.path().extension() == ".yaml") { - files.push_back(entry.path().generic_string()); - } - } - return files; -}(); + std::vector files; + for (const auto& entry : std::filesystem::directory_iterator("./invalid_config_files_router/")) + { + if (entry.path().extension() == ".yaml") + { + files.push_back(entry.path().generic_string()); + } + } + return files; + }(); } // namespace test /** From 170d9fca012728de4110eafd8fedad2237e97560 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Wed, 24 Jun 2026 14:56:21 +0200 Subject: [PATCH 09/10] Fix string too long on Windows Signed-off-by: David Laseca Perez --- ddsrouter_yaml/CMakeLists.txt | 12 ++++++++++++ .../ddsrouter_yaml/DdsRouterConfigSchema.hpp.in | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ddsrouter_yaml/CMakeLists.txt b/ddsrouter_yaml/CMakeLists.txt index 5b9b27a26..fe43dd1bf 100644 --- a/ddsrouter_yaml/CMakeLists.txt +++ b/ddsrouter_yaml/CMakeLists.txt @@ -80,6 +80,18 @@ compile_test_library( file(READ "${PROJECT_SOURCE_DIR}/../resources/configurations/ddsrouter_config_schema.json" DDSROUTER_CONFIG_SCHEMA_CONTENT) +# Split into <=16000-char chunks to work around MSVC C2026 string literal size limit. +# Adjacent string literals are concatenated by the compiler. +string(LENGTH "${DDSROUTER_CONFIG_SCHEMA_CONTENT}" _schema_len) +set(_chunk_size 16000) +set(DDSROUTER_CONFIG_SCHEMA_CHUNKS "") +set(_offset 0) +while(_offset LESS _schema_len) + string(SUBSTRING "${DDSROUTER_CONFIG_SCHEMA_CONTENT}" ${_offset} ${_chunk_size} _chunk) + string(APPEND DDSROUTER_CONFIG_SCHEMA_CHUNKS " R\"json(${_chunk})json\"\n") + math(EXPR _offset "${_offset} + ${_chunk_size}") +endwhile() + configure_file( "${PROJECT_SOURCE_DIR}/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in" "${CMAKE_CURRENT_BINARY_DIR}/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp" diff --git a/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in b/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in index 87e41126a..99bdad12d 100644 --- a/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in +++ b/ddsrouter_yaml/include/ddsrouter_yaml/DdsRouterConfigSchema.hpp.in @@ -14,4 +14,5 @@ #pragma once -static const char* DDSROUTER_CONFIG_SCHEMA = R"json(@DDSROUTER_CONFIG_SCHEMA_CONTENT@)json"; +static const char* DDSROUTER_CONFIG_SCHEMA = +@DDSROUTER_CONFIG_SCHEMA_CHUNKS@; From 75f0a192e497b02505ef1cc0eb0dee5f8fcbb872 Mon Sep 17 00:00:00 2001 From: David Laseca Perez Date: Thu, 25 Jun 2026 11:27:30 +0200 Subject: [PATCH 10/10] Compile with C++17 to use filesystem in the tests Signed-off-by: David Laseca Perez --- ddsrouter_yaml/project_settings.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ddsrouter_yaml/project_settings.cmake b/ddsrouter_yaml/project_settings.cmake index 6fb1db5f0..40d8da377 100644 --- a/ddsrouter_yaml/project_settings.cmake +++ b/ddsrouter_yaml/project_settings.cmake @@ -37,3 +37,6 @@ set(fastdds_MINIMUM_VERSION "3.0.0") set(MODULE_DEPENDENCIES $<$:iphlpapi$Shlwapi> ${MODULE_FIND_PACKAGES}) + +set(MODULE_CPP_VERSION + C++17)